From 1beb3e6606d6f121429e2537a6e31284ec423863 Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 03:45:16 +0200 Subject: [PATCH 01/22] feat: install spatie --- apps/backend/composer.json | 1 + apps/backend/composer.lock | 85 +++++++- apps/backend/config/permission.php | 202 ++++++++++++++++++ ..._10_04_014456_create_permission_tables.php | 136 ++++++++++++ 4 files changed, 423 insertions(+), 1 deletion(-) create mode 100644 apps/backend/config/permission.php create mode 100644 apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php diff --git a/apps/backend/composer.json b/apps/backend/composer.json index 035cc6c..d45a532 100644 --- a/apps/backend/composer.json +++ b/apps/backend/composer.json @@ -13,6 +13,7 @@ "laravel/framework": "^12.0", "laravel/sanctum": "^4.0", "laravel/tinker": "^2.10.1", + "spatie/laravel-permission": "^6.21", "tymon/jwt-auth": "^2.2" }, "require-dev": { diff --git a/apps/backend/composer.lock b/apps/backend/composer.lock index 29a905e..9e157e7 100644 --- a/apps/backend/composer.lock +++ b/apps/backend/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": "d46537a24eff9bb87f645ae19c244518", + "content-hash": "e464c4dd898fe7d7d602dc2c39992ac2", "packages": [ { "name": "brick/math", @@ -3478,6 +3478,89 @@ }, "time": "2025-09-04T20:59:21+00:00" }, + { + "name": "spatie/laravel-permission", + "version": "6.21.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-permission.git", + "reference": "6a118e8855dfffcd90403aab77bbf35a03db51b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/6a118e8855dfffcd90403aab77bbf35a03db51b3", + "reference": "6a118e8855dfffcd90403aab77bbf35a03db51b3", + "shasum": "" + }, + "require": { + "illuminate/auth": "^8.12|^9.0|^10.0|^11.0|^12.0", + "illuminate/container": "^8.12|^9.0|^10.0|^11.0|^12.0", + "illuminate/contracts": "^8.12|^9.0|^10.0|^11.0|^12.0", + "illuminate/database": "^8.12|^9.0|^10.0|^11.0|^12.0", + "php": "^8.0" + }, + "require-dev": { + "laravel/passport": "^11.0|^12.0", + "laravel/pint": "^1.0", + "orchestra/testbench": "^6.23|^7.0|^8.0|^9.0|^10.0", + "phpunit/phpunit": "^9.4|^10.1|^11.5" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\Permission\\PermissionServiceProvider" + ] + }, + "branch-alias": { + "dev-main": "6.x-dev", + "dev-master": "6.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\Permission\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Permission handling for Laravel 8.0 and up", + "homepage": "https://github.com/spatie/laravel-permission", + "keywords": [ + "acl", + "laravel", + "permission", + "permissions", + "rbac", + "roles", + "security", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-permission/issues", + "source": "https://github.com/spatie/laravel-permission/tree/6.21.0" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2025-07-23T16:08:05+00:00" + }, { "name": "symfony/clock", "version": "v7.3.0", diff --git a/apps/backend/config/permission.php b/apps/backend/config/permission.php new file mode 100644 index 0000000..f39f6b5 --- /dev/null +++ b/apps/backend/config/permission.php @@ -0,0 +1,202 @@ + [ + + /* + * When using the "HasPermissions" trait from this package, we need to know which + * Eloquent model should be used to retrieve your permissions. Of course, it + * is often just the "Permission" model but you may use whatever you like. + * + * The model you want to use as a Permission model needs to implement the + * `Spatie\Permission\Contracts\Permission` contract. + */ + + 'permission' => Spatie\Permission\Models\Permission::class, + + /* + * When using the "HasRoles" trait from this package, we need to know which + * Eloquent model should be used to retrieve your roles. Of course, it + * is often just the "Role" model but you may use whatever you like. + * + * The model you want to use as a Role model needs to implement the + * `Spatie\Permission\Contracts\Role` contract. + */ + + 'role' => Spatie\Permission\Models\Role::class, + + ], + + 'table_names' => [ + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your roles. We have chosen a basic + * default value but you may easily change it to any table you like. + */ + + 'roles' => 'roles', + + /* + * When using the "HasPermissions" trait from this package, we need to know which + * table should be used to retrieve your permissions. We have chosen a basic + * default value but you may easily change it to any table you like. + */ + + 'permissions' => 'permissions', + + /* + * When using the "HasPermissions" trait from this package, we need to know which + * table should be used to retrieve your models permissions. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'model_has_permissions' => 'model_has_permissions', + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your models roles. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'model_has_roles' => 'model_has_roles', + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your roles permissions. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'role_has_permissions' => 'role_has_permissions', + ], + + 'column_names' => [ + /* + * Change this if you want to name the related pivots other than defaults + */ + 'role_pivot_key' => null, // default 'role_id', + 'permission_pivot_key' => null, // default 'permission_id', + + /* + * Change this if you want to name the related model primary key other than + * `model_id`. + * + * For example, this would be nice if your primary keys are all UUIDs. In + * that case, name this `model_uuid`. + */ + + 'model_morph_key' => 'model_id', + + /* + * Change this if you want to use the teams feature and your related model's + * foreign key is other than `team_id`. + */ + + 'team_foreign_key' => 'team_id', + ], + + /* + * When set to true, the method for checking permissions will be registered on the gate. + * Set this to false if you want to implement custom logic for checking permissions. + */ + + 'register_permission_check_method' => true, + + /* + * When set to true, Laravel\Octane\Events\OperationTerminated event listener will be registered + * this will refresh permissions on every TickTerminated, TaskTerminated and RequestTerminated + * NOTE: This should not be needed in most cases, but an Octane/Vapor combination benefited from it. + */ + 'register_octane_reset_listener' => false, + + /* + * Events will fire when a role or permission is assigned/unassigned: + * \Spatie\Permission\Events\RoleAttached + * \Spatie\Permission\Events\RoleDetached + * \Spatie\Permission\Events\PermissionAttached + * \Spatie\Permission\Events\PermissionDetached + * + * To enable, set to true, and then create listeners to watch these events. + */ + 'events_enabled' => false, + + /* + * Teams Feature. + * When set to true the package implements teams using the 'team_foreign_key'. + * If you want the migrations to register the 'team_foreign_key', you must + * set this to true before doing the migration. + * If you already did the migration then you must make a new migration to also + * add 'team_foreign_key' to 'roles', 'model_has_roles', and 'model_has_permissions' + * (view the latest version of this package's migration file) + */ + + 'teams' => false, + + /* + * The class to use to resolve the permissions team id + */ + 'team_resolver' => \Spatie\Permission\DefaultTeamResolver::class, + + /* + * Passport Client Credentials Grant + * When set to true the package will use Passports Client to check permissions + */ + + 'use_passport_client_credentials' => false, + + /* + * When set to true, the required permission names are added to exception messages. + * This could be considered an information leak in some contexts, so the default + * setting is false here for optimum safety. + */ + + 'display_permission_in_exception' => false, + + /* + * When set to true, the required role names are added to exception messages. + * This could be considered an information leak in some contexts, so the default + * setting is false here for optimum safety. + */ + + 'display_role_in_exception' => false, + + /* + * By default wildcard permission lookups are disabled. + * See documentation to understand supported syntax. + */ + + 'enable_wildcard_permission' => false, + + /* + * The class to use for interpreting wildcard permissions. + * If you need to modify delimiters, override the class and specify its name here. + */ + // 'wildcard_permission' => Spatie\Permission\WildcardPermission::class, + + /* Cache-specific settings */ + + 'cache' => [ + + /* + * By default all permissions are cached for 24 hours to speed up performance. + * When permissions or roles are updated the cache is flushed automatically. + */ + + 'expiration_time' => \DateInterval::createFromDateString('24 hours'), + + /* + * The cache key used to store all permissions. + */ + + 'key' => 'spatie.permission.cache', + + /* + * You may optionally indicate a specific cache driver to use for permission and + * role caching using any of the `store` drivers listed in the cache.php config + * file. Using 'default' here means to use the `default` set in cache.php. + */ + + 'store' => 'default', + ], +]; diff --git a/apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php b/apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php new file mode 100644 index 0000000..ce4d9d2 --- /dev/null +++ b/apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php @@ -0,0 +1,136 @@ +engine('InnoDB'); + $table->bigIncrements('id'); // permission id + $table->string('name'); // For MyISAM use string('name', 225); // (or 166 for InnoDB with Redundant/Compact row format) + $table->string('guard_name'); // For MyISAM use string('guard_name', 25); + $table->timestamps(); + + $table->unique(['name', 'guard_name']); + }); + + Schema::create($tableNames['roles'], static function (Blueprint $table) use ($teams, $columnNames) { + // $table->engine('InnoDB'); + $table->bigIncrements('id'); // role id + if ($teams || config('permission.testing')) { // permission.testing is a fix for sqlite testing + $table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable(); + $table->index($columnNames['team_foreign_key'], 'roles_team_foreign_key_index'); + } + $table->string('name'); // For MyISAM use string('name', 225); // (or 166 for InnoDB with Redundant/Compact row format) + $table->string('guard_name'); // For MyISAM use string('guard_name', 25); + $table->timestamps(); + if ($teams || config('permission.testing')) { + $table->unique([$columnNames['team_foreign_key'], 'name', 'guard_name']); + } else { + $table->unique(['name', 'guard_name']); + } + }); + + Schema::create($tableNames['model_has_permissions'], static function (Blueprint $table) use ($tableNames, $columnNames, $pivotPermission, $teams) { + $table->unsignedBigInteger($pivotPermission); + + $table->string('model_type'); + $table->unsignedBigInteger($columnNames['model_morph_key']); + $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index'); + + $table->foreign($pivotPermission) + ->references('id') // permission id + ->on($tableNames['permissions']) + ->onDelete('cascade'); + if ($teams) { + $table->unsignedBigInteger($columnNames['team_foreign_key']); + $table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index'); + + $table->primary([$columnNames['team_foreign_key'], $pivotPermission, $columnNames['model_morph_key'], 'model_type'], + 'model_has_permissions_permission_model_type_primary'); + } else { + $table->primary([$pivotPermission, $columnNames['model_morph_key'], 'model_type'], + 'model_has_permissions_permission_model_type_primary'); + } + + }); + + Schema::create($tableNames['model_has_roles'], static function (Blueprint $table) use ($tableNames, $columnNames, $pivotRole, $teams) { + $table->unsignedBigInteger($pivotRole); + + $table->string('model_type'); + $table->unsignedBigInteger($columnNames['model_morph_key']); + $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index'); + + $table->foreign($pivotRole) + ->references('id') // role id + ->on($tableNames['roles']) + ->onDelete('cascade'); + if ($teams) { + $table->unsignedBigInteger($columnNames['team_foreign_key']); + $table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index'); + + $table->primary([$columnNames['team_foreign_key'], $pivotRole, $columnNames['model_morph_key'], 'model_type'], + 'model_has_roles_role_model_type_primary'); + } else { + $table->primary([$pivotRole, $columnNames['model_morph_key'], 'model_type'], + 'model_has_roles_role_model_type_primary'); + } + }); + + Schema::create($tableNames['role_has_permissions'], static function (Blueprint $table) use ($tableNames, $pivotRole, $pivotPermission) { + $table->unsignedBigInteger($pivotPermission); + $table->unsignedBigInteger($pivotRole); + + $table->foreign($pivotPermission) + ->references('id') // permission id + ->on($tableNames['permissions']) + ->onDelete('cascade'); + + $table->foreign($pivotRole) + ->references('id') // role id + ->on($tableNames['roles']) + ->onDelete('cascade'); + + $table->primary([$pivotPermission, $pivotRole], 'role_has_permissions_permission_id_role_id_primary'); + }); + + app('cache') + ->store(config('permission.cache.store') != 'default' ? config('permission.cache.store') : null) + ->forget(config('permission.cache.key')); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + $tableNames = config('permission.table_names'); + + if (empty($tableNames)) { + throw new \Exception('Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.'); + } + + Schema::drop($tableNames['role_has_permissions']); + Schema::drop($tableNames['model_has_roles']); + Schema::drop($tableNames['model_has_permissions']); + Schema::drop($tableNames['roles']); + Schema::drop($tableNames['permissions']); + } +}; From bf2926b5f5973f3de8d2f71015c4b5b257b2ec13 Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 03:57:34 +0200 Subject: [PATCH 02/22] refactor: enable uuid's for spatie --- ..._10_04_014456_create_permission_tables.php | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php b/apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php index ce4d9d2..f2a9952 100644 --- a/apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php +++ b/apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php @@ -22,7 +22,7 @@ public function up(): void Schema::create($tableNames['permissions'], static function (Blueprint $table) { // $table->engine('InnoDB'); - $table->bigIncrements('id'); // permission id + $table->uuid('uuid')->primary()->unique(); $table->string('name'); // For MyISAM use string('name', 225); // (or 166 for InnoDB with Redundant/Compact row format) $table->string('guard_name'); // For MyISAM use string('guard_name', 25); $table->timestamps(); @@ -32,7 +32,7 @@ public function up(): void Schema::create($tableNames['roles'], static function (Blueprint $table) use ($teams, $columnNames) { // $table->engine('InnoDB'); - $table->bigIncrements('id'); // role id + $table->uuid('uuid')->primary()->unique(); // role id if ($teams || config('permission.testing')) { // permission.testing is a fix for sqlite testing $table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable(); $table->index($columnNames['team_foreign_key'], 'roles_team_foreign_key_index'); @@ -50,12 +50,12 @@ public function up(): void Schema::create($tableNames['model_has_permissions'], static function (Blueprint $table) use ($tableNames, $columnNames, $pivotPermission, $teams) { $table->unsignedBigInteger($pivotPermission); - $table->string('model_type'); - $table->unsignedBigInteger($columnNames['model_morph_key']); + $table->uuid($pivotPermission); + $table->uuid($columnNames['model_morph_key']); $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index'); $table->foreign($pivotPermission) - ->references('id') // permission id + ->references('uuid') ->on($tableNames['permissions']) ->onDelete('cascade'); if ($teams) { @@ -72,14 +72,14 @@ public function up(): void }); Schema::create($tableNames['model_has_roles'], static function (Blueprint $table) use ($tableNames, $columnNames, $pivotRole, $teams) { - $table->unsignedBigInteger($pivotRole); + $table->uuid($pivotRole); $table->string('model_type'); - $table->unsignedBigInteger($columnNames['model_morph_key']); + $table->uuid($columnNames['model_morph_key']); $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index'); $table->foreign($pivotRole) - ->references('id') // role id + ->references('uuid') // role id ->on($tableNames['roles']) ->onDelete('cascade'); if ($teams) { @@ -95,16 +95,16 @@ public function up(): void }); Schema::create($tableNames['role_has_permissions'], static function (Blueprint $table) use ($tableNames, $pivotRole, $pivotPermission) { - $table->unsignedBigInteger($pivotPermission); - $table->unsignedBigInteger($pivotRole); + $table->uuid($pivotPermission); + $table->uuid($pivotRole); $table->foreign($pivotPermission) - ->references('id') // permission id + ->references('uuid') // permission id ->on($tableNames['permissions']) ->onDelete('cascade'); $table->foreign($pivotRole) - ->references('id') // role id + ->references('uuid') // role id ->on($tableNames['roles']) ->onDelete('cascade'); From f358fe033d7f3d6262c6c42dfe2ada8bd19881e9 Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 04:04:42 +0200 Subject: [PATCH 03/22] fix: broken spatie migration --- .../migrations/2025_10_04_014456_create_permission_tables.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php b/apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php index f2a9952..7333b0d 100644 --- a/apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php +++ b/apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php @@ -48,9 +48,8 @@ public function up(): void }); Schema::create($tableNames['model_has_permissions'], static function (Blueprint $table) use ($tableNames, $columnNames, $pivotPermission, $teams) { - $table->unsignedBigInteger($pivotPermission); - $table->uuid($pivotPermission); + $table->string('model_type'); $table->uuid($columnNames['model_morph_key']); $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index'); From 5c72ed0d18a3ae67b1bc3a172b180d79212e751b Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 04:05:57 +0200 Subject: [PATCH 04/22] fix: composer lock in git --- apps/backend/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/backend/.gitignore b/apps/backend/.gitignore index b71b1ea..e8c17ba 100644 --- a/apps/backend/.gitignore +++ b/apps/backend/.gitignore @@ -22,3 +22,4 @@ Homestead.json Homestead.yaml Thumbs.db +composer.lock From 8f4b2286f1d130491e7ae1ae5882df8d9f2d7a10 Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 05:28:30 +0200 Subject: [PATCH 05/22] feat: implement permissions --- .../app/Http/Controllers/AuthController.php | 10 +++++ apps/backend/app/Models/Permission.php | 23 ++++++++++ apps/backend/app/Models/Role.php | 23 ++++++++++ apps/backend/app/Models/User.php | 3 +- apps/backend/config/permission.php | 13 ++---- ..._10_04_014456_create_permission_tables.php | 13 +++--- ...04_021216_create_roles_and_permissions.php | 44 +++++++++++++++++++ apps/backend/routes/api.php | 1 + 8 files changed, 114 insertions(+), 16 deletions(-) create mode 100644 apps/backend/app/Models/Permission.php create mode 100644 apps/backend/app/Models/Role.php create mode 100644 apps/backend/database/migrations/2025_10_04_021216_create_roles_and_permissions.php diff --git a/apps/backend/app/Http/Controllers/AuthController.php b/apps/backend/app/Http/Controllers/AuthController.php index ebd8da9..7ca51d6 100644 --- a/apps/backend/app/Http/Controllers/AuthController.php +++ b/apps/backend/app/Http/Controllers/AuthController.php @@ -11,6 +11,16 @@ class AuthController extends Controller { + public function getPermissions() + { + $user = Auth::user(); + if (!$user) { + return response()->json(['error' => 'User not found'], 404); + } + + $permissions = $user->getPermissionNames(); + return response()->json(['permissions' => $permissions]); + } public function register(Request $request) { $request->validate([ diff --git a/apps/backend/app/Models/Permission.php b/apps/backend/app/Models/Permission.php new file mode 100644 index 0000000..9d59986 --- /dev/null +++ b/apps/backend/app/Models/Permission.php @@ -0,0 +1,23 @@ +id)) { + $permission->id = (string) Str::uuid(); + } + }); + } +} diff --git a/apps/backend/app/Models/Role.php b/apps/backend/app/Models/Role.php new file mode 100644 index 0000000..638d754 --- /dev/null +++ b/apps/backend/app/Models/Role.php @@ -0,0 +1,23 @@ +id)) { + $role->id = (string) Str::uuid(); + } + }); + } +} diff --git a/apps/backend/app/Models/User.php b/apps/backend/app/Models/User.php index 6cce4d5..5b89e63 100644 --- a/apps/backend/app/Models/User.php +++ b/apps/backend/app/Models/User.php @@ -6,13 +6,14 @@ use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Illuminate\Support\Str; +use Spatie\Permission\Traits\HasRoles; use Tymon\JWTAuth\Contracts\JWTSubject; class User extends Authenticatable implements JWTSubject { /** @use HasFactory<\Database\Factories\UserFactory> */ - use HasFactory, Notifiable; + use HasFactory, Notifiable, HasRoles; protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/config/permission.php b/apps/backend/config/permission.php index f39f6b5..add3d0a 100644 --- a/apps/backend/config/permission.php +++ b/apps/backend/config/permission.php @@ -1,9 +1,7 @@ [ - /* * When using the "HasPermissions" trait from this package, we need to know which * Eloquent model should be used to retrieve your permissions. Of course, it @@ -13,7 +11,7 @@ * `Spatie\Permission\Contracts\Permission` contract. */ - 'permission' => Spatie\Permission\Models\Permission::class, + 'permission' => App\Models\Permission::class, /* * When using the "HasRoles" trait from this package, we need to know which @@ -24,12 +22,10 @@ * `Spatie\Permission\Contracts\Role` contract. */ - 'role' => Spatie\Permission\Models\Role::class, - + 'role' => App\Models\Role::class, ], 'table_names' => [ - /* * When using the "HasRoles" trait from this package, we need to know which * table should be used to retrieve your roles. We have chosen a basic @@ -75,8 +71,8 @@ /* * Change this if you want to name the related pivots other than defaults */ - 'role_pivot_key' => null, // default 'role_id', - 'permission_pivot_key' => null, // default 'permission_id', + 'role_pivot_key' => 'role_id', // explicitly set for UUID support + 'permission_pivot_key' => 'permission_id', // explicitly set for UUID support /* * Change this if you want to name the related model primary key other than @@ -177,7 +173,6 @@ /* Cache-specific settings */ 'cache' => [ - /* * By default all permissions are cached for 24 hours to speed up performance. * When permissions or roles are updated the cache is flushed automatically. diff --git a/apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php b/apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php index 7333b0d..d577463 100644 --- a/apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php +++ b/apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php @@ -3,6 +3,7 @@ use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Query\Expression; return new class extends Migration { @@ -22,7 +23,7 @@ public function up(): void Schema::create($tableNames['permissions'], static function (Blueprint $table) { // $table->engine('InnoDB'); - $table->uuid('uuid')->primary()->unique(); + $table->uuid('id')->primary()->default(new Expression('(UUID())')); $table->string('name'); // For MyISAM use string('name', 225); // (or 166 for InnoDB with Redundant/Compact row format) $table->string('guard_name'); // For MyISAM use string('guard_name', 25); $table->timestamps(); @@ -32,7 +33,7 @@ public function up(): void Schema::create($tableNames['roles'], static function (Blueprint $table) use ($teams, $columnNames) { // $table->engine('InnoDB'); - $table->uuid('uuid')->primary()->unique(); // role id + $table->uuid('id')->primary()->default(new Expression('(UUID())')); if ($teams || config('permission.testing')) { // permission.testing is a fix for sqlite testing $table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable(); $table->index($columnNames['team_foreign_key'], 'roles_team_foreign_key_index'); @@ -54,7 +55,7 @@ public function up(): void $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index'); $table->foreign($pivotPermission) - ->references('uuid') + ->references('id') ->on($tableNames['permissions']) ->onDelete('cascade'); if ($teams) { @@ -78,7 +79,7 @@ public function up(): void $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index'); $table->foreign($pivotRole) - ->references('uuid') // role id + ->references('id') // role id ->on($tableNames['roles']) ->onDelete('cascade'); if ($teams) { @@ -98,12 +99,12 @@ public function up(): void $table->uuid($pivotRole); $table->foreign($pivotPermission) - ->references('uuid') // permission id + ->references('id') // permission id ->on($tableNames['permissions']) ->onDelete('cascade'); $table->foreign($pivotRole) - ->references('uuid') // role id + ->references('id') // role id ->on($tableNames['roles']) ->onDelete('cascade'); diff --git a/apps/backend/database/migrations/2025_10_04_021216_create_roles_and_permissions.php b/apps/backend/database/migrations/2025_10_04_021216_create_roles_and_permissions.php new file mode 100644 index 0000000..37e9174 --- /dev/null +++ b/apps/backend/database/migrations/2025_10_04_021216_create_roles_and_permissions.php @@ -0,0 +1,44 @@ + 'apprentice']); + $mentor_role = \App\Models\Role::create(['name' => 'mentor']); + $supervisor_role = \App\Models\Role::create(['name' => 'supervisor']); + $admin_role = \App\Models\Role::create(['name' => 'admin']); + + $view_projects = \App\Models\Permission::create(['name' => 'view projects']); + $edit_projects = \App\Models\Permission::create(['name' => 'edit projects']); + $create_projects = \App\Models\Permission::create(['name' => 'create projects']); + $manage_projects = \App\Models\Permission::create(['name' => 'manage projects']); + + $view_users = \App\Models\Permission::create(['name' => 'view users']); + $manage_users = \App\Models\Permission::create(['name' => 'manage users']); + + $view_years = \App\Models\Permission::create(['name' => 'view years']); + $manage_years = \App\Models\Permission::create(['name' => 'manage years']); + + $view_criteria = \App\Models\Permission::create(['name' => 'view criteria']); + $manage_criteria = \App\Models\Permission::create(['name' => 'manage criteria']); + + $apprentice_role->givePermissionTo($edit_projects, $view_criteria); + $mentor_role->givePermissionTo($create_projects, $view_projects, $view_users, $view_years, $view_criteria, $manage_criteria); + $supervisor_role->givePermissionTo($manage_projects, $view_users, $manage_years, $manage_criteria, $manage_years); + $admin_role->givePermissionTo(\App\Models\Permission::all()); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + + } +}; diff --git a/apps/backend/routes/api.php b/apps/backend/routes/api.php index 2b830a8..b9517d3 100644 --- a/apps/backend/routes/api.php +++ b/apps/backend/routes/api.php @@ -11,6 +11,7 @@ Route::middleware('jwt')->group(function () { Route::get('/user', [AuthController::class, 'getUser']); + Route::get('/permissions', [AuthController::class, 'getPermissions']); Route::put('/user', [AuthController::class, 'updateUser']); Route::post('/logout', [AuthController::class, 'logout']); }); From e28054b9dfbdfae62100a642348c232d04ae9c6a Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 05:59:42 +0200 Subject: [PATCH 06/22] feat: implement rudimentary project creation --- .../Http/Controllers/ProjectController.php | 46 +++++++++++++++++++ .../app/Http/Controllers/YearController.php | 33 +++++++++++++ apps/backend/app/Models/Chapter.php | 8 ++++ apps/backend/app/Models/Project.php | 10 ++++ apps/backend/app/Models/Year.php | 6 +++ apps/backend/routes/api.php | 13 +++++- 6 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 apps/backend/app/Http/Controllers/ProjectController.php create mode 100644 apps/backend/app/Http/Controllers/YearController.php diff --git a/apps/backend/app/Http/Controllers/ProjectController.php b/apps/backend/app/Http/Controllers/ProjectController.php new file mode 100644 index 0000000..6037cc7 --- /dev/null +++ b/apps/backend/app/Http/Controllers/ProjectController.php @@ -0,0 +1,46 @@ +validate([ + 'year_id' => 'required|exists:years,id', + 'owner_id' => 'required|exists:users,id', + 'name' => 'required|string|max:255', + 'start_date' => 'required|date', + 'end_date' => 'required|date|after_or_equal:start_date', + 'description' => 'nullable|string', + ]); + + $project = new Project($validatedData); + $project->save(); + + $new_project_id = $project->id; + + $defaultChapters = [ + ['name' => 'Ausführung und Resultat der Arbeit', 'type' => 'execution'], + ['name' => 'Dokumentation', 'type' => 'documentation'], + ['name' => 'Präsentation und Fachgespräch', 'type' => 'presentation'], + ]; + foreach ($defaultChapters as $chapterData) { + $chapter = new Chapter([ + 'project_id' => $new_project_id, + 'title' => $chapterData['name'], + 'type' => $chapterData['type'], + 'subtitle' => '', + ]); + $chapter->save(); + } + + + return response()->json(['message' => 'Project created successfully', 'project' => $project], 201); + } +} diff --git a/apps/backend/app/Http/Controllers/YearController.php b/apps/backend/app/Http/Controllers/YearController.php new file mode 100644 index 0000000..d2f663a --- /dev/null +++ b/apps/backend/app/Http/Controllers/YearController.php @@ -0,0 +1,33 @@ +all()); + return response()->json($year, 201); + } + + public function update(Request $request, $id) { + $year = Year::findOrFail($id); + $year->update($request->all()); + return response()->json($year, 200); + } + + public function delete($id) { + Year::findOrFail($id)->delete(); + return response()->json(null, 204); + } +} diff --git a/apps/backend/app/Models/Chapter.php b/apps/backend/app/Models/Chapter.php index 112054a..4c6dbc6 100644 --- a/apps/backend/app/Models/Chapter.php +++ b/apps/backend/app/Models/Chapter.php @@ -3,9 +3,17 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Str; class Chapter extends Model { + protected $fillable = [ + 'project_id', + 'type', + 'title', + 'subtitle', + ]; + protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/Project.php b/apps/backend/app/Models/Project.php index d83884b..60dd0ef 100644 --- a/apps/backend/app/Models/Project.php +++ b/apps/backend/app/Models/Project.php @@ -3,9 +3,19 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Str; class Project extends Model { + protected $fillable = [ + 'year_id', + 'name', + 'owner_id', + 'description', + 'start_date', + 'end_date', + ]; + protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/Year.php b/apps/backend/app/Models/Year.php index 52d6d72..84a3110 100644 --- a/apps/backend/app/Models/Year.php +++ b/apps/backend/app/Models/Year.php @@ -3,9 +3,15 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Str; class Year extends Model { + protected $fillable = [ + 'year', + 'is_active', + ]; + protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/routes/api.php b/apps/backend/routes/api.php index b9517d3..27668e7 100644 --- a/apps/backend/routes/api.php +++ b/apps/backend/routes/api.php @@ -3,7 +3,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; use App\Http\Controllers\AuthController; -use App\Http\Controllers\UserController; +use App\Http\Controllers\ProjectController; Route::post('/register', [AuthController::class, 'register']); @@ -16,3 +16,14 @@ Route::post('/logout', [AuthController::class, 'logout']); }); +Route::middleware('jwt')->prefix('project')->group(function () { + Route::post('/create', [ProjectController::class, 'createProject']); +}); + +Route::middleware('jwt')->prefix('year')->group(function () { + Route::get('/', [App\Http\Controllers\YearController::class, 'index']); + Route::get('/{id}', [App\Http\Controllers\YearController::class, 'show']); + Route::post('/', [App\Http\Controllers\YearController::class, 'store']); + Route::put('/{id}', [App\Http\Controllers\YearController::class, 'update']); + Route::delete('/{id}', [App\Http\Controllers\YearController::class, 'delete']); +}); From 04291cf701f4b8e44fa3808322b1bbcb601ef80b Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 06:07:42 +0200 Subject: [PATCH 07/22] fix: import Str in all models --- apps/backend/app/Models/Criterion.php | 1 + apps/backend/app/Models/Glossary.php | 1 + apps/backend/app/Models/Image.php | 1 + apps/backend/app/Models/Section.php | 1 + apps/backend/app/Models/SubCriterion.php | 1 + apps/backend/app/Models/Table.php | 1 + apps/backend/app/Models/TextBlock.php | 1 + apps/backend/app/Models/TimeBlock.php | 1 + apps/backend/app/Models/UserMeta.php | 1 + apps/backend/app/Models/UserSubCriterion.php | 1 + 10 files changed, 10 insertions(+) diff --git a/apps/backend/app/Models/Criterion.php b/apps/backend/app/Models/Criterion.php index 480535b..57b393f 100644 --- a/apps/backend/app/Models/Criterion.php +++ b/apps/backend/app/Models/Criterion.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Str; class Criterion extends Model { diff --git a/apps/backend/app/Models/Glossary.php b/apps/backend/app/Models/Glossary.php index a9acc92..c0b20ac 100644 --- a/apps/backend/app/Models/Glossary.php +++ b/apps/backend/app/Models/Glossary.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Str; class Glossary extends Model { diff --git a/apps/backend/app/Models/Image.php b/apps/backend/app/Models/Image.php index ff62cb5..026712e 100644 --- a/apps/backend/app/Models/Image.php +++ b/apps/backend/app/Models/Image.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Str; class Image extends Model { diff --git a/apps/backend/app/Models/Section.php b/apps/backend/app/Models/Section.php index 7793d34..ef7ee75 100644 --- a/apps/backend/app/Models/Section.php +++ b/apps/backend/app/Models/Section.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Str; class Section extends Model { diff --git a/apps/backend/app/Models/SubCriterion.php b/apps/backend/app/Models/SubCriterion.php index b88ae1d..c2b44c1 100644 --- a/apps/backend/app/Models/SubCriterion.php +++ b/apps/backend/app/Models/SubCriterion.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Str; class SubCriterion extends Model { diff --git a/apps/backend/app/Models/Table.php b/apps/backend/app/Models/Table.php index 0e464ce..dee312f 100644 --- a/apps/backend/app/Models/Table.php +++ b/apps/backend/app/Models/Table.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Str; class Table extends Model { diff --git a/apps/backend/app/Models/TextBlock.php b/apps/backend/app/Models/TextBlock.php index 868da61..0416ac8 100644 --- a/apps/backend/app/Models/TextBlock.php +++ b/apps/backend/app/Models/TextBlock.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Str; class TextBlock extends Model { diff --git a/apps/backend/app/Models/TimeBlock.php b/apps/backend/app/Models/TimeBlock.php index 4cbd701..e53a043 100644 --- a/apps/backend/app/Models/TimeBlock.php +++ b/apps/backend/app/Models/TimeBlock.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Str; class TimeBlock extends Model { diff --git a/apps/backend/app/Models/UserMeta.php b/apps/backend/app/Models/UserMeta.php index 57d7ccb..11dea30 100644 --- a/apps/backend/app/Models/UserMeta.php +++ b/apps/backend/app/Models/UserMeta.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Str; class UserMeta extends Model { diff --git a/apps/backend/app/Models/UserSubCriterion.php b/apps/backend/app/Models/UserSubCriterion.php index 668074f..e7c7913 100644 --- a/apps/backend/app/Models/UserSubCriterion.php +++ b/apps/backend/app/Models/UserSubCriterion.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Str; class UserSubCriterion extends Model { From 7cb3750009a9c881c20848edbdee8875855bc290 Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 06:15:01 +0200 Subject: [PATCH 08/22] feat; add fillable atributes to all modells --- apps/backend/app/Models/AiRating.php | 7 +++++++ apps/backend/app/Models/Criterion.php | 7 +++++++ apps/backend/app/Models/Glossary.php | 6 ++++++ apps/backend/app/Models/Image.php | 8 ++++++++ apps/backend/app/Models/Section.php | 9 +++++++++ apps/backend/app/Models/SubCriterion.php | 5 +++++ apps/backend/app/Models/Table.php | 8 ++++++++ apps/backend/app/Models/TextBlock.php | 8 ++++++++ apps/backend/app/Models/TimeBlock.php | 8 ++++++++ apps/backend/app/Models/UserMeta.php | 6 ++++++ apps/backend/app/Models/UserSubCriterion.php | 6 ++++++ 11 files changed, 78 insertions(+) diff --git a/apps/backend/app/Models/AiRating.php b/apps/backend/app/Models/AiRating.php index 8fee9ea..5da4533 100644 --- a/apps/backend/app/Models/AiRating.php +++ b/apps/backend/app/Models/AiRating.php @@ -7,6 +7,13 @@ class AiRating extends Model { + protected $fillable = [ + 'section_id', + 'rating', + 'rating_description', + 'rating_checksum', + ]; + protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/Criterion.php b/apps/backend/app/Models/Criterion.php index 57b393f..1d245c7 100644 --- a/apps/backend/app/Models/Criterion.php +++ b/apps/backend/app/Models/Criterion.php @@ -7,6 +7,13 @@ class Criterion extends Model { + protected $fillable = [ + 'year_id', + 'title', + 'description', + 'special_for_project_id', + ]; + protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/Glossary.php b/apps/backend/app/Models/Glossary.php index c0b20ac..cc1e90f 100644 --- a/apps/backend/app/Models/Glossary.php +++ b/apps/backend/app/Models/Glossary.php @@ -7,6 +7,12 @@ class Glossary extends Model { + protected $fillable = [ + 'project_id', + 'term', + 'definition', + ]; + protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/Image.php b/apps/backend/app/Models/Image.php index 026712e..53c2624 100644 --- a/apps/backend/app/Models/Image.php +++ b/apps/backend/app/Models/Image.php @@ -7,6 +7,14 @@ class Image extends Model { + protected $fillable = [ + 'section_id', + 'position', + 'image_data', + 'description', + 'source', + ]; + protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/Section.php b/apps/backend/app/Models/Section.php index ef7ee75..46eeb88 100644 --- a/apps/backend/app/Models/Section.php +++ b/apps/backend/app/Models/Section.php @@ -7,6 +7,15 @@ class Section extends Model { + protected $fillable = [ + 'chapter_id', + 'parent_id', + 'position', + 'title', + 'subtitle', + 'rating_checksum', + ]; + protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/SubCriterion.php b/apps/backend/app/Models/SubCriterion.php index c2b44c1..9f1c62c 100644 --- a/apps/backend/app/Models/SubCriterion.php +++ b/apps/backend/app/Models/SubCriterion.php @@ -7,6 +7,11 @@ class SubCriterion extends Model { + protected $fillable = [ + 'criteria_id', + 'description', + ]; + protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/Table.php b/apps/backend/app/Models/Table.php index dee312f..afb7a27 100644 --- a/apps/backend/app/Models/Table.php +++ b/apps/backend/app/Models/Table.php @@ -7,6 +7,14 @@ class Table extends Model { + protected $fillable = [ + 'section_id', + 'position', + 'heading', + 'markdown_table', + 'source', + ]; + protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/TextBlock.php b/apps/backend/app/Models/TextBlock.php index 0416ac8..f59af2c 100644 --- a/apps/backend/app/Models/TextBlock.php +++ b/apps/backend/app/Models/TextBlock.php @@ -7,6 +7,14 @@ class TextBlock extends Model { + protected $fillable = [ + 'section_id', + 'position', + 'heading', + 'text', + 'source', + ]; + protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/TimeBlock.php b/apps/backend/app/Models/TimeBlock.php index e53a043..e6f7a33 100644 --- a/apps/backend/app/Models/TimeBlock.php +++ b/apps/backend/app/Models/TimeBlock.php @@ -7,6 +7,14 @@ class TimeBlock extends Model { + protected $fillable = [ + 'project_id', + 'description', + 'is_chore', + 'start_time', + 'end_time', + ]; + protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/UserMeta.php b/apps/backend/app/Models/UserMeta.php index 11dea30..46da327 100644 --- a/apps/backend/app/Models/UserMeta.php +++ b/apps/backend/app/Models/UserMeta.php @@ -7,6 +7,12 @@ class UserMeta extends Model { + protected $fillable = [ + 'user_id', + 'meta_key', + 'meta_value', + ]; + protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/UserSubCriterion.php b/apps/backend/app/Models/UserSubCriterion.php index e7c7913..b70a768 100644 --- a/apps/backend/app/Models/UserSubCriterion.php +++ b/apps/backend/app/Models/UserSubCriterion.php @@ -7,6 +7,12 @@ class UserSubCriterion extends Model { + protected $fillable = [ + 'sub_criteria_id', + 'user_id', + 'is_fulfilled', + ]; + protected $keyType = 'string'; public $incrementing = false; From b2ae2cf3e2e6510fe9ce83a8c6ebc3640310f8a3 Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 06:27:40 +0200 Subject: [PATCH 09/22] feat: create factories --- apps/backend/app/Models/AiRating.php | 4 ++ apps/backend/app/Models/Chapter.php | 4 ++ apps/backend/app/Models/Criterion.php | 4 ++ apps/backend/app/Models/Glossary.php | 4 ++ apps/backend/app/Models/Image.php | 4 ++ apps/backend/app/Models/Permission.php | 4 ++ apps/backend/app/Models/Project.php | 4 ++ apps/backend/app/Models/Role.php | 8 +++- apps/backend/app/Models/Section.php | 4 ++ apps/backend/app/Models/SubCriterion.php | 4 ++ apps/backend/app/Models/Table.php | 4 ++ apps/backend/app/Models/TextBlock.php | 4 ++ apps/backend/app/Models/TimeBlock.php | 4 ++ apps/backend/app/Models/UserMeta.php | 4 ++ apps/backend/app/Models/UserSubCriterion.php | 4 ++ apps/backend/app/Models/Year.php | 4 ++ .../database/factories/AiRatingFactory.php | 35 +++++++++++++++++ .../database/factories/ChapterFactory.php | 35 +++++++++++++++++ .../database/factories/CriterionFactory.php | 34 ++++++++++++++++ .../database/factories/GlossaryFactory.php | 34 ++++++++++++++++ .../database/factories/ImageFactory.php | 36 +++++++++++++++++ .../database/factories/PermissionFactory.php | 32 +++++++++++++++ .../database/factories/ProjectFactory.php | 38 ++++++++++++++++++ .../database/factories/RoleFactory.php | 32 +++++++++++++++ .../database/factories/SectionFactory.php | 37 ++++++++++++++++++ .../factories/SubCriterionFactory.php | 33 ++++++++++++++++ .../database/factories/TableFactory.php | 36 +++++++++++++++++ .../database/factories/TextBlockFactory.php | 36 +++++++++++++++++ .../database/factories/TimeBlockFactory.php | 39 +++++++++++++++++++ .../database/factories/UserMetaFactory.php | 34 ++++++++++++++++ .../factories/UserSubCriterionFactory.php | 35 +++++++++++++++++ .../database/factories/YearFactory.php | 32 +++++++++++++++ 32 files changed, 624 insertions(+), 2 deletions(-) create mode 100644 apps/backend/database/factories/AiRatingFactory.php create mode 100644 apps/backend/database/factories/ChapterFactory.php create mode 100644 apps/backend/database/factories/CriterionFactory.php create mode 100644 apps/backend/database/factories/GlossaryFactory.php create mode 100644 apps/backend/database/factories/ImageFactory.php create mode 100644 apps/backend/database/factories/PermissionFactory.php create mode 100644 apps/backend/database/factories/ProjectFactory.php create mode 100644 apps/backend/database/factories/RoleFactory.php create mode 100644 apps/backend/database/factories/SectionFactory.php create mode 100644 apps/backend/database/factories/SubCriterionFactory.php create mode 100644 apps/backend/database/factories/TableFactory.php create mode 100644 apps/backend/database/factories/TextBlockFactory.php create mode 100644 apps/backend/database/factories/TimeBlockFactory.php create mode 100644 apps/backend/database/factories/UserMetaFactory.php create mode 100644 apps/backend/database/factories/UserSubCriterionFactory.php create mode 100644 apps/backend/database/factories/YearFactory.php diff --git a/apps/backend/app/Models/AiRating.php b/apps/backend/app/Models/AiRating.php index 5da4533..156d08c 100644 --- a/apps/backend/app/Models/AiRating.php +++ b/apps/backend/app/Models/AiRating.php @@ -2,11 +2,15 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class AiRating extends Model { + /** @use HasFactory<\Database\Factories\AiRatingFactory> */ + use HasFactory; + protected $fillable = [ 'section_id', 'rating', diff --git a/apps/backend/app/Models/Chapter.php b/apps/backend/app/Models/Chapter.php index 4c6dbc6..a671487 100644 --- a/apps/backend/app/Models/Chapter.php +++ b/apps/backend/app/Models/Chapter.php @@ -2,11 +2,15 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class Chapter extends Model { + /** @use HasFactory<\Database\Factories\ChapterFactory> */ + use HasFactory; + protected $fillable = [ 'project_id', 'type', diff --git a/apps/backend/app/Models/Criterion.php b/apps/backend/app/Models/Criterion.php index 1d245c7..22d67c5 100644 --- a/apps/backend/app/Models/Criterion.php +++ b/apps/backend/app/Models/Criterion.php @@ -2,11 +2,15 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class Criterion extends Model { + /** @use HasFactory<\Database\Factories\CriterionFactory> */ + use HasFactory; + protected $fillable = [ 'year_id', 'title', diff --git a/apps/backend/app/Models/Glossary.php b/apps/backend/app/Models/Glossary.php index cc1e90f..b9fef5c 100644 --- a/apps/backend/app/Models/Glossary.php +++ b/apps/backend/app/Models/Glossary.php @@ -2,11 +2,15 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class Glossary extends Model { + /** @use HasFactory<\Database\Factories\GlossaryFactory> */ + use HasFactory; + protected $fillable = [ 'project_id', 'term', diff --git a/apps/backend/app/Models/Image.php b/apps/backend/app/Models/Image.php index 53c2624..eb63bdc 100644 --- a/apps/backend/app/Models/Image.php +++ b/apps/backend/app/Models/Image.php @@ -2,11 +2,15 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class Image extends Model { + /** @use HasFactory<\Database\Factories\ImageFactory> */ + use HasFactory; + protected $fillable = [ 'section_id', 'position', diff --git a/apps/backend/app/Models/Permission.php b/apps/backend/app/Models/Permission.php index 9d59986..a8ce061 100644 --- a/apps/backend/app/Models/Permission.php +++ b/apps/backend/app/Models/Permission.php @@ -2,11 +2,15 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Spatie\Permission\Models\Permission as SpatiePermission; use Illuminate\Support\Str; class Permission extends SpatiePermission { + /** @use HasFactory<\Database\Factories\PermissionFactory> */ + use HasFactory; + protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/Project.php b/apps/backend/app/Models/Project.php index 60dd0ef..6e7ac7d 100644 --- a/apps/backend/app/Models/Project.php +++ b/apps/backend/app/Models/Project.php @@ -2,11 +2,15 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class Project extends Model { + /** @use HasFactory<\Database\Factories\ProjectFactory> */ + use HasFactory; + protected $fillable = [ 'year_id', 'name', diff --git a/apps/backend/app/Models/Role.php b/apps/backend/app/Models/Role.php index 638d754..f0811af 100644 --- a/apps/backend/app/Models/Role.php +++ b/apps/backend/app/Models/Role.php @@ -2,11 +2,15 @@ namespace App\Models; -use Spatie\Permission\Models\Permission as SpatiePermission; +use Illuminate\Database\Eloquent\Factories\HasFactory; +use Spatie\Permission\Models\Role as SpatieRole; use Illuminate\Support\Str; -class Role extends SpatiePermission +class Role extends SpatieRole { + /** @use HasFactory<\Database\Factories\RoleFactory> */ + use HasFactory; + protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/Section.php b/apps/backend/app/Models/Section.php index 46eeb88..47ba4ad 100644 --- a/apps/backend/app/Models/Section.php +++ b/apps/backend/app/Models/Section.php @@ -2,11 +2,15 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class Section extends Model { + /** @use HasFactory<\Database\Factories\SectionFactory> */ + use HasFactory; + protected $fillable = [ 'chapter_id', 'parent_id', diff --git a/apps/backend/app/Models/SubCriterion.php b/apps/backend/app/Models/SubCriterion.php index 9f1c62c..ba46f73 100644 --- a/apps/backend/app/Models/SubCriterion.php +++ b/apps/backend/app/Models/SubCriterion.php @@ -2,11 +2,15 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class SubCriterion extends Model { + /** @use HasFactory<\Database\Factories\SubCriterionFactory> */ + use HasFactory; + protected $fillable = [ 'criteria_id', 'description', diff --git a/apps/backend/app/Models/Table.php b/apps/backend/app/Models/Table.php index afb7a27..bf5c8fb 100644 --- a/apps/backend/app/Models/Table.php +++ b/apps/backend/app/Models/Table.php @@ -2,11 +2,15 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class Table extends Model { + /** @use HasFactory<\Database\Factories\TableFactory> */ + use HasFactory; + protected $fillable = [ 'section_id', 'position', diff --git a/apps/backend/app/Models/TextBlock.php b/apps/backend/app/Models/TextBlock.php index f59af2c..fae22fb 100644 --- a/apps/backend/app/Models/TextBlock.php +++ b/apps/backend/app/Models/TextBlock.php @@ -2,11 +2,15 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class TextBlock extends Model { + /** @use HasFactory<\Database\Factories\TextBlockFactory> */ + use HasFactory; + protected $fillable = [ 'section_id', 'position', diff --git a/apps/backend/app/Models/TimeBlock.php b/apps/backend/app/Models/TimeBlock.php index e6f7a33..519c9d8 100644 --- a/apps/backend/app/Models/TimeBlock.php +++ b/apps/backend/app/Models/TimeBlock.php @@ -2,11 +2,15 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class TimeBlock extends Model { + /** @use HasFactory<\Database\Factories\TimeBlockFactory> */ + use HasFactory; + protected $fillable = [ 'project_id', 'description', diff --git a/apps/backend/app/Models/UserMeta.php b/apps/backend/app/Models/UserMeta.php index 46da327..ffad010 100644 --- a/apps/backend/app/Models/UserMeta.php +++ b/apps/backend/app/Models/UserMeta.php @@ -2,11 +2,15 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class UserMeta extends Model { + /** @use HasFactory<\Database\Factories\UserMetaFactory> */ + use HasFactory; + protected $fillable = [ 'user_id', 'meta_key', diff --git a/apps/backend/app/Models/UserSubCriterion.php b/apps/backend/app/Models/UserSubCriterion.php index b70a768..b7b94b9 100644 --- a/apps/backend/app/Models/UserSubCriterion.php +++ b/apps/backend/app/Models/UserSubCriterion.php @@ -2,11 +2,15 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class UserSubCriterion extends Model { + /** @use HasFactory<\Database\Factories\UserSubCriterionFactory> */ + use HasFactory; + protected $fillable = [ 'sub_criteria_id', 'user_id', diff --git a/apps/backend/app/Models/Year.php b/apps/backend/app/Models/Year.php index 84a3110..9f9e06b 100644 --- a/apps/backend/app/Models/Year.php +++ b/apps/backend/app/Models/Year.php @@ -2,11 +2,15 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; class Year extends Model { + /** @use HasFactory<\Database\Factories\YearFactory> */ + use HasFactory; + protected $fillable = [ 'year', 'is_active', diff --git a/apps/backend/database/factories/AiRatingFactory.php b/apps/backend/database/factories/AiRatingFactory.php new file mode 100644 index 0000000..0b5abe5 --- /dev/null +++ b/apps/backend/database/factories/AiRatingFactory.php @@ -0,0 +1,35 @@ + + */ +class AiRatingFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var string + */ + protected $model = AiRating::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'section_id' => Section::factory(), + 'rating' => $this->faker->numberBetween(1, 10), + 'rating_description' => $this->faker->paragraph(), + 'rating_checksum' => $this->faker->sha256(), + ]; + } +} diff --git a/apps/backend/database/factories/ChapterFactory.php b/apps/backend/database/factories/ChapterFactory.php new file mode 100644 index 0000000..550c7b0 --- /dev/null +++ b/apps/backend/database/factories/ChapterFactory.php @@ -0,0 +1,35 @@ + + */ +class ChapterFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var string + */ + protected $model = Chapter::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'project_id' => Project::factory(), + 'type' => $this->faker->randomElement(['introduction', 'main', 'conclusion']), + 'title' => $this->faker->sentence(3), + 'subtitle' => $this->faker->sentence(5), + ]; + } +} diff --git a/apps/backend/database/factories/CriterionFactory.php b/apps/backend/database/factories/CriterionFactory.php new file mode 100644 index 0000000..58f72f8 --- /dev/null +++ b/apps/backend/database/factories/CriterionFactory.php @@ -0,0 +1,34 @@ + + */ +class CriterionFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var string + */ + protected $model = Criterion::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'year_id' => \App\Models\Year::factory(), + 'title' => $this->faker->sentence(3), + 'description' => $this->faker->paragraph(), + 'special_for_project_id' => null, + ]; + } +} diff --git a/apps/backend/database/factories/GlossaryFactory.php b/apps/backend/database/factories/GlossaryFactory.php new file mode 100644 index 0000000..b82ede2 --- /dev/null +++ b/apps/backend/database/factories/GlossaryFactory.php @@ -0,0 +1,34 @@ + + */ +class GlossaryFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var string + */ + protected $model = Glossary::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'project_id' => Project::factory(), + 'term' => $this->faker->word(), + 'definition' => $this->faker->paragraph(), + ]; + } +} diff --git a/apps/backend/database/factories/ImageFactory.php b/apps/backend/database/factories/ImageFactory.php new file mode 100644 index 0000000..01d477a --- /dev/null +++ b/apps/backend/database/factories/ImageFactory.php @@ -0,0 +1,36 @@ + + */ +class ImageFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var string + */ + protected $model = Image::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'section_id' => Section::factory(), + 'position' => $this->faker->numberBetween(1, 10), + 'image_data' => $this->faker->imageUrl(640, 480), + 'description' => $this->faker->sentence(), + 'source' => $this->faker->url(), + ]; + } +} diff --git a/apps/backend/database/factories/PermissionFactory.php b/apps/backend/database/factories/PermissionFactory.php new file mode 100644 index 0000000..db369d0 --- /dev/null +++ b/apps/backend/database/factories/PermissionFactory.php @@ -0,0 +1,32 @@ + + */ +class PermissionFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var string + */ + protected $model = Permission::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'name' => $this->faker->unique()->word(), + 'guard_name' => 'web', + ]; + } +} diff --git a/apps/backend/database/factories/ProjectFactory.php b/apps/backend/database/factories/ProjectFactory.php new file mode 100644 index 0000000..29f8f30 --- /dev/null +++ b/apps/backend/database/factories/ProjectFactory.php @@ -0,0 +1,38 @@ + + */ +class ProjectFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var string + */ + protected $model = Project::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'year_id' => Year::factory(), + 'name' => $this->faker->sentence(3), + 'owner_id' => User::factory(), + 'description' => $this->faker->paragraph(), + 'start_date' => $this->faker->date(), + 'end_date' => $this->faker->date(), + ]; + } +} diff --git a/apps/backend/database/factories/RoleFactory.php b/apps/backend/database/factories/RoleFactory.php new file mode 100644 index 0000000..0d7e177 --- /dev/null +++ b/apps/backend/database/factories/RoleFactory.php @@ -0,0 +1,32 @@ + + */ +class RoleFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var string + */ + protected $model = Role::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'name' => $this->faker->unique()->word(), + 'guard_name' => 'web', + ]; + } +} diff --git a/apps/backend/database/factories/SectionFactory.php b/apps/backend/database/factories/SectionFactory.php new file mode 100644 index 0000000..3d290e8 --- /dev/null +++ b/apps/backend/database/factories/SectionFactory.php @@ -0,0 +1,37 @@ + + */ +class SectionFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var string + */ + protected $model = Section::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'chapter_id' => Chapter::factory(), + 'parent_id' => null, + 'position' => $this->faker->numberBetween(1, 10), + 'title' => $this->faker->sentence(3), + 'subtitle' => $this->faker->sentence(5), + 'rating_checksum' => $this->faker->sha256(), + ]; + } +} diff --git a/apps/backend/database/factories/SubCriterionFactory.php b/apps/backend/database/factories/SubCriterionFactory.php new file mode 100644 index 0000000..58822a0 --- /dev/null +++ b/apps/backend/database/factories/SubCriterionFactory.php @@ -0,0 +1,33 @@ + + */ +class SubCriterionFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var string + */ + protected $model = SubCriterion::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'criteria_id' => Criterion::factory(), + 'description' => $this->faker->paragraph(), + ]; + } +} diff --git a/apps/backend/database/factories/TableFactory.php b/apps/backend/database/factories/TableFactory.php new file mode 100644 index 0000000..0abd005 --- /dev/null +++ b/apps/backend/database/factories/TableFactory.php @@ -0,0 +1,36 @@ + + */ +class TableFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var string + */ + protected $model = Table::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'section_id' => Section::factory(), + 'position' => $this->faker->numberBetween(1, 10), + 'heading' => $this->faker->sentence(3), + 'markdown_table' => '| Header 1 | Header 2 |\n|----------|----------|\n| Cell 1 | Cell 2 |', + 'source' => $this->faker->url(), + ]; + } +} diff --git a/apps/backend/database/factories/TextBlockFactory.php b/apps/backend/database/factories/TextBlockFactory.php new file mode 100644 index 0000000..3b8ebc9 --- /dev/null +++ b/apps/backend/database/factories/TextBlockFactory.php @@ -0,0 +1,36 @@ + + */ +class TextBlockFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var string + */ + protected $model = TextBlock::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'section_id' => Section::factory(), + 'position' => $this->faker->numberBetween(1, 10), + 'heading' => $this->faker->sentence(3), + 'text' => $this->faker->paragraphs(3, true), + 'source' => $this->faker->url(), + ]; + } +} diff --git a/apps/backend/database/factories/TimeBlockFactory.php b/apps/backend/database/factories/TimeBlockFactory.php new file mode 100644 index 0000000..97ac8ab --- /dev/null +++ b/apps/backend/database/factories/TimeBlockFactory.php @@ -0,0 +1,39 @@ + + */ +class TimeBlockFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var string + */ + protected $model = TimeBlock::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + $startTime = $this->faker->dateTimeThisYear(); + $endTime = (clone $startTime)->modify('+' . $this->faker->numberBetween(1, 8) . ' hours'); + + return [ + 'project_id' => Project::factory(), + 'description' => $this->faker->sentence(), + 'is_chore' => $this->faker->boolean(), + 'start_time' => $startTime, + 'end_time' => $endTime, + ]; + } +} diff --git a/apps/backend/database/factories/UserMetaFactory.php b/apps/backend/database/factories/UserMetaFactory.php new file mode 100644 index 0000000..f527703 --- /dev/null +++ b/apps/backend/database/factories/UserMetaFactory.php @@ -0,0 +1,34 @@ + + */ +class UserMetaFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var string + */ + protected $model = UserMeta::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'user_id' => User::factory(), + 'meta_key' => $this->faker->word(), + 'meta_value' => $this->faker->sentence(), + ]; + } +} diff --git a/apps/backend/database/factories/UserSubCriterionFactory.php b/apps/backend/database/factories/UserSubCriterionFactory.php new file mode 100644 index 0000000..95118a1 --- /dev/null +++ b/apps/backend/database/factories/UserSubCriterionFactory.php @@ -0,0 +1,35 @@ + + */ +class UserSubCriterionFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var string + */ + protected $model = UserSubCriterion::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'sub_criteria_id' => SubCriterion::factory(), + 'user_id' => User::factory(), + 'is_fulfilled' => $this->faker->boolean(), + ]; + } +} diff --git a/apps/backend/database/factories/YearFactory.php b/apps/backend/database/factories/YearFactory.php new file mode 100644 index 0000000..5ee596b --- /dev/null +++ b/apps/backend/database/factories/YearFactory.php @@ -0,0 +1,32 @@ + + */ +class YearFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var string + */ + protected $model = Year::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'year' => $this->faker->numberBetween(2020, 2030), + 'is_active' => $this->faker->boolean(), + ]; + } +} From df6e9c95defcf05e99746209346aa19c8db6f040 Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 07:07:25 +0200 Subject: [PATCH 10/22] fix: wrong naming conventions --- ...able.php => 2025_10_03_225024_create_glossaries_table.php} | 4 ++-- ...able.php => 2025_10_03_225024_create_user_metas_table.php} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename apps/backend/database/migrations/{2025_10_03_225024_create_glossary_table.php => 2025_10_03_225024_create_glossaries_table.php} (85%) rename apps/backend/database/migrations/{2025_10_03_225024_create_user_meta_table.php => 2025_10_03_225024_create_user_metas_table.php} (85%) diff --git a/apps/backend/database/migrations/2025_10_03_225024_create_glossary_table.php b/apps/backend/database/migrations/2025_10_03_225024_create_glossaries_table.php similarity index 85% rename from apps/backend/database/migrations/2025_10_03_225024_create_glossary_table.php rename to apps/backend/database/migrations/2025_10_03_225024_create_glossaries_table.php index f7c83d2..21e3ad1 100644 --- a/apps/backend/database/migrations/2025_10_03_225024_create_glossary_table.php +++ b/apps/backend/database/migrations/2025_10_03_225024_create_glossaries_table.php @@ -11,7 +11,7 @@ */ public function up(): void { - Schema::create('glossary', function (Blueprint $table) { + Schema::create('glossaries', function (Blueprint $table) { $table->char('id', 36)->primary(); $table->char('project_id', 36); $table->string('term'); @@ -27,6 +27,6 @@ public function up(): void */ public function down(): void { - Schema::dropIfExists('glossary'); + Schema::dropIfExists('glossaries'); } }; diff --git a/apps/backend/database/migrations/2025_10_03_225024_create_user_meta_table.php b/apps/backend/database/migrations/2025_10_03_225024_create_user_metas_table.php similarity index 85% rename from apps/backend/database/migrations/2025_10_03_225024_create_user_meta_table.php rename to apps/backend/database/migrations/2025_10_03_225024_create_user_metas_table.php index 437cd2c..21812ad 100644 --- a/apps/backend/database/migrations/2025_10_03_225024_create_user_meta_table.php +++ b/apps/backend/database/migrations/2025_10_03_225024_create_user_metas_table.php @@ -11,7 +11,7 @@ */ public function up(): void { - Schema::create('user_meta', function (Blueprint $table) { + Schema::create('user_metas', function (Blueprint $table) { $table->char('id', 36)->primary(); $table->char('user_id', 36); $table->string('meta_key'); @@ -27,6 +27,6 @@ public function up(): void */ public function down(): void { - Schema::dropIfExists('user_meta'); + Schema::dropIfExists('user_metas'); } }; From 4eb4bbd3262de3f32575606836c9d7c53d7a63a8 Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 07:07:46 +0200 Subject: [PATCH 11/22] fix: old user format --- apps/backend/database/factories/UserFactory.php | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/apps/backend/database/factories/UserFactory.php b/apps/backend/database/factories/UserFactory.php index 584104c..61026e8 100644 --- a/apps/backend/database/factories/UserFactory.php +++ b/apps/backend/database/factories/UserFactory.php @@ -24,21 +24,12 @@ class UserFactory extends Factory public function definition(): array { return [ - 'name' => fake()->name(), + 'first_name' => fake()->firstName(), + 'last_name' => fake()->lastName(), 'email' => fake()->unique()->safeEmail(), - 'email_verified_at' => now(), 'password' => static::$password ??= Hash::make('password'), 'remember_token' => Str::random(10), ]; } - /** - * Indicate that the model's email address should be unverified. - */ - public function unverified(): static - { - return $this->state(fn (array $attributes) => [ - 'email_verified_at' => null, - ]); - } } From 01ffa888c320fe17be8ceab874b42e56e20d6b8c Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 07:08:04 +0200 Subject: [PATCH 12/22] feat: implement database seeder --- .../database/seeders/DatabaseSeeder.php | 89 +++++++++++++++++-- 1 file changed, 81 insertions(+), 8 deletions(-) diff --git a/apps/backend/database/seeders/DatabaseSeeder.php b/apps/backend/database/seeders/DatabaseSeeder.php index d01a0ef..ac75561 100644 --- a/apps/backend/database/seeders/DatabaseSeeder.php +++ b/apps/backend/database/seeders/DatabaseSeeder.php @@ -2,22 +2,95 @@ namespace Database\Seeders; -use App\Models\User; -// use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; +use App\Models\{Year, User, Project, Chapter, Section, TextBlock, Table as TableModel, Image, AiRating, Glossary, Criterion, SubCriterion, TimeBlock, UserMeta, UserSubCriterion}; class DatabaseSeeder extends Seeder { /** - * Seed the application's database. + * Seed the application's database with simple demo data. */ public function run(): void { - // User::factory(10)->create(); + // Base data + $years = Year::factory()->count(rand(5, 10))->create(); + $users = User::factory()->count(rand(5, 10))->create(); - User::factory()->create([ - 'name' => 'Test User', - 'email' => 'test@example.com', - ]); + // Projects linked to existing Years and Users + $projects = Project::factory()->count(rand(5, 10))->make()->each(function (Project $project) use ($years, $users) { + $project->year_id = $years->random()->id; + $project->owner_id = $users->random()->id; + $project->save(); + }); + + // Chapters linked to Projects + $chapters = Chapter::factory()->count(rand(5, 10))->make()->each(function (Chapter $chapter) use ($projects) { + $chapter->project_id = $projects->random()->id; + $chapter->save(); + }); + + // Sections linked to Chapters + $sections = Section::factory()->count(rand(5, 10))->make()->each(function (Section $section) use ($chapters) { + $section->chapter_id = $chapters->random()->id; + $section->parent_id = null; + $section->save(); + }); + + // Content linked to Sections + TextBlock::factory()->count(rand(5, 10))->make()->each(function (TextBlock $tb) use ($sections) { + $tb->section_id = $sections->random()->id; + $tb->save(); + }); + + TableModel::factory()->count(rand(5, 10))->make()->each(function (TableModel $tbl) use ($sections) { + $tbl->section_id = $sections->random()->id; + $tbl->save(); + }); + + Image::factory()->count(rand(5, 10))->make()->each(function (Image $img) use ($sections) { + $img->section_id = $sections->random()->id; + $img->save(); + }); + + AiRating::factory()->count(rand(5, 10))->make()->each(function (AiRating $r) use ($sections) { + $r->section_id = $sections->random()->id; + $r->save(); + }); + + // Glossary terms linked to Projects + Glossary::factory()->count(rand(5, 10))->make()->each(function (Glossary $g) use ($projects) { + $g->project_id = $projects->random()->id; + $g->save(); + }); + + // Criteria and SubCriteria linked to Years/Criteria + $criteria = Criterion::factory()->count(rand(5, 10))->make()->each(function (Criterion $c) use ($years) { + $c->year_id = $years->random()->id; + $c->special_for_project_id = null; + $c->save(); + }); + + $subCriteria = SubCriterion::factory()->count(rand(5, 10))->make()->each(function (SubCriterion $sc) use ($criteria) { + $sc->criteria_id = $criteria->random()->id; + $sc->save(); + }); + + // Time tracking linked to Projects + TimeBlock::factory()->count(rand(5, 10))->make()->each(function (TimeBlock $tb) use ($projects) { + $tb->project_id = $projects->random()->id; + $tb->save(); + }); + + // User meta and user-sub-criteria + UserMeta::factory()->count(rand(5, 10))->make()->each(function (UserMeta $um) use ($users) { + $um->user_id = $users->random()->id; + $um->save(); + }); + + UserSubCriterion::factory()->count(rand(5, 10))->make()->each(function (UserSubCriterion $usc) use ($users, $subCriteria) { + $usc->user_id = $users->random()->id; + $usc->sub_criteria_id = $subCriteria->random()->id; + $usc->save(); + }); } } From b8372daac869f9693db68f6a32247dc8d4ffa22a Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 07:15:07 +0200 Subject: [PATCH 13/22] refactor: format --- .../app/Http/Controllers/AuthController.php | 13 +- .../Http/Controllers/ProjectController.php | 7 +- .../app/Http/Controllers/YearController.php | 15 +- apps/backend/app/Models/AiRating.php | 7 +- apps/backend/app/Models/Chapter.php | 7 +- apps/backend/app/Models/Criterion.php | 7 +- apps/backend/app/Models/Glossary.php | 6 +- apps/backend/app/Models/Image.php | 8 +- apps/backend/app/Models/Project.php | 9 +- apps/backend/app/Models/SubCriterion.php | 5 +- apps/backend/app/Models/Table.php | 8 +- apps/backend/app/Models/TextBlock.php | 8 +- apps/backend/app/Models/TimeBlock.php | 8 +- apps/backend/app/Models/User.php | 14 +- apps/backend/app/Models/UserMeta.php | 6 +- apps/backend/app/Models/UserSubCriterion.php | 6 +- apps/backend/app/Models/Year.php | 5 +- apps/backend/bootstrap/app.php | 14 +- apps/backend/bootstrap/providers.php | 4 +- apps/backend/config/app.php | 8 +- apps/backend/config/auth.php | 2 - apps/backend/config/cache.php | 11 +- apps/backend/config/database.php | 27 +-- apps/backend/config/filesystems.php | 6 +- apps/backend/config/jwt.php | 15 +- apps/backend/config/logging.php | 7 +- apps/backend/config/mail.php | 19 +- apps/backend/config/queue.php | 4 - apps/backend/config/sanctum.php | 20 +- apps/backend/config/services.php | 2 - apps/backend/config/session.php | 7 +- .../database/factories/TableFactory.php | 3 +- .../database/factories/UserFactory.php | 3 +- .../0001_01_01_000000_create_users_table.php | 3 +- .../0001_01_01_000001_create_cache_table.php | 3 +- .../0001_01_01_000002_create_jobs_table.php | 3 +- ...1_2025_10_03_225024_create_years_table.php | 3 +- ...025_10_03_225024_create_projects_table.php | 3 +- ...025_10_03_225025_create_chapters_table.php | 3 +- ...025_10_03_225025_create_sections_table.php | 3 +- ...36_create_personal_access_tokens_table.php | 3 +- ...025_10_03_225024_create_criteria_table.php | 3 +- ...5_10_03_225024_create_glossaries_table.php | 3 +- ...10_03_225024_create_sub_criteria_table.php | 3 +- ..._10_03_225024_create_time_blocks_table.php | 3 +- ...5_10_03_225024_create_user_metas_table.php | 3 +- ..._225024_create_user_sub_criteria_table.php | 3 +- ...5_10_03_225025_create_ai_ratings_table.php | 3 +- .../2025_10_03_225025_create_images_table.php | 3 +- .../2025_10_03_225025_create_tables_table.php | 3 +- ..._10_03_225025_create_text_blocks_table.php | 3 +- ..._10_04_014456_create_permission_tables.php | 132 +++++++++---- ...04_021216_create_roles_and_permissions.php | 25 ++- .../database/seeders/DatabaseSeeder.php | 179 ++++++++++++------ apps/backend/package-lock.json | 46 +++++ apps/backend/package.json | 2 + apps/backend/public/index.php | 6 +- apps/backend/routes/api.php | 25 +-- 58 files changed, 406 insertions(+), 354 deletions(-) diff --git a/apps/backend/app/Http/Controllers/AuthController.php b/apps/backend/app/Http/Controllers/AuthController.php index 7ca51d6..309b098 100644 --- a/apps/backend/app/Http/Controllers/AuthController.php +++ b/apps/backend/app/Http/Controllers/AuthController.php @@ -43,10 +43,13 @@ public function register(Request $request) return response()->json(['error' => 'Could not create token'], 500); } - return response()->json([ - 'token' => $token, - 'user' => $user, - ], 201); + return response()->json( + [ + 'token' => $token, + 'user' => $user, + ], + 201, + ); } public function login(Request $request) @@ -54,7 +57,7 @@ public function login(Request $request) $credentials = $request->only('email', 'password'); try { - if (!$token = JWTAuth::attempt($credentials)) { + if (!($token = JWTAuth::attempt($credentials))) { return response()->json(['error' => 'Invalid credentials'], 401); } } catch (JWTException $e) { diff --git a/apps/backend/app/Http/Controllers/ProjectController.php b/apps/backend/app/Http/Controllers/ProjectController.php index 6037cc7..823091e 100644 --- a/apps/backend/app/Http/Controllers/ProjectController.php +++ b/apps/backend/app/Http/Controllers/ProjectController.php @@ -6,7 +6,6 @@ use App\Models\Project; use App\Models\Chapter; - class ProjectController extends Controller { public function createProject(Request $request) @@ -40,7 +39,9 @@ public function createProject(Request $request) $chapter->save(); } - - return response()->json(['message' => 'Project created successfully', 'project' => $project], 201); + return response()->json( + ['message' => 'Project created successfully', 'project' => $project], + 201, + ); } } diff --git a/apps/backend/app/Http/Controllers/YearController.php b/apps/backend/app/Http/Controllers/YearController.php index d2f663a..de2e460 100644 --- a/apps/backend/app/Http/Controllers/YearController.php +++ b/apps/backend/app/Http/Controllers/YearController.php @@ -7,26 +7,31 @@ class YearController extends Controller { - public function index() { + public function index() + { return Year::all(); } - public function show($id) { + public function show($id) + { return Year::findOrFail($id); } - public function store(Request $request) { + public function store(Request $request) + { $year = Year::create($request->all()); return response()->json($year, 201); } - public function update(Request $request, $id) { + public function update(Request $request, $id) + { $year = Year::findOrFail($id); $year->update($request->all()); return response()->json($year, 200); } - public function delete($id) { + public function delete($id) + { Year::findOrFail($id)->delete(); return response()->json(null, 204); } diff --git a/apps/backend/app/Models/AiRating.php b/apps/backend/app/Models/AiRating.php index 156d08c..c807633 100644 --- a/apps/backend/app/Models/AiRating.php +++ b/apps/backend/app/Models/AiRating.php @@ -11,12 +11,7 @@ class AiRating extends Model /** @use HasFactory<\Database\Factories\AiRatingFactory> */ use HasFactory; - protected $fillable = [ - 'section_id', - 'rating', - 'rating_description', - 'rating_checksum', - ]; + protected $fillable = ['section_id', 'rating', 'rating_description', 'rating_checksum']; protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/Chapter.php b/apps/backend/app/Models/Chapter.php index a671487..f0704f5 100644 --- a/apps/backend/app/Models/Chapter.php +++ b/apps/backend/app/Models/Chapter.php @@ -11,12 +11,7 @@ class Chapter extends Model /** @use HasFactory<\Database\Factories\ChapterFactory> */ use HasFactory; - protected $fillable = [ - 'project_id', - 'type', - 'title', - 'subtitle', - ]; + protected $fillable = ['project_id', 'type', 'title', 'subtitle']; protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/Criterion.php b/apps/backend/app/Models/Criterion.php index 22d67c5..b2ec149 100644 --- a/apps/backend/app/Models/Criterion.php +++ b/apps/backend/app/Models/Criterion.php @@ -11,12 +11,7 @@ class Criterion extends Model /** @use HasFactory<\Database\Factories\CriterionFactory> */ use HasFactory; - protected $fillable = [ - 'year_id', - 'title', - 'description', - 'special_for_project_id', - ]; + protected $fillable = ['year_id', 'title', 'description', 'special_for_project_id']; protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/Glossary.php b/apps/backend/app/Models/Glossary.php index b9fef5c..1ce9e0d 100644 --- a/apps/backend/app/Models/Glossary.php +++ b/apps/backend/app/Models/Glossary.php @@ -11,11 +11,7 @@ class Glossary extends Model /** @use HasFactory<\Database\Factories\GlossaryFactory> */ use HasFactory; - protected $fillable = [ - 'project_id', - 'term', - 'definition', - ]; + protected $fillable = ['project_id', 'term', 'definition']; protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/Image.php b/apps/backend/app/Models/Image.php index eb63bdc..d43870c 100644 --- a/apps/backend/app/Models/Image.php +++ b/apps/backend/app/Models/Image.php @@ -11,13 +11,7 @@ class Image extends Model /** @use HasFactory<\Database\Factories\ImageFactory> */ use HasFactory; - protected $fillable = [ - 'section_id', - 'position', - 'image_data', - 'description', - 'source', - ]; + protected $fillable = ['section_id', 'position', 'image_data', 'description', 'source']; protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/Project.php b/apps/backend/app/Models/Project.php index 6e7ac7d..b1a2f88 100644 --- a/apps/backend/app/Models/Project.php +++ b/apps/backend/app/Models/Project.php @@ -11,14 +11,7 @@ class Project extends Model /** @use HasFactory<\Database\Factories\ProjectFactory> */ use HasFactory; - protected $fillable = [ - 'year_id', - 'name', - 'owner_id', - 'description', - 'start_date', - 'end_date', - ]; + protected $fillable = ['year_id', 'name', 'owner_id', 'description', 'start_date', 'end_date']; protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/SubCriterion.php b/apps/backend/app/Models/SubCriterion.php index ba46f73..7ac086e 100644 --- a/apps/backend/app/Models/SubCriterion.php +++ b/apps/backend/app/Models/SubCriterion.php @@ -11,10 +11,7 @@ class SubCriterion extends Model /** @use HasFactory<\Database\Factories\SubCriterionFactory> */ use HasFactory; - protected $fillable = [ - 'criteria_id', - 'description', - ]; + protected $fillable = ['criteria_id', 'description']; protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/Table.php b/apps/backend/app/Models/Table.php index bf5c8fb..d771e4a 100644 --- a/apps/backend/app/Models/Table.php +++ b/apps/backend/app/Models/Table.php @@ -11,13 +11,7 @@ class Table extends Model /** @use HasFactory<\Database\Factories\TableFactory> */ use HasFactory; - protected $fillable = [ - 'section_id', - 'position', - 'heading', - 'markdown_table', - 'source', - ]; + protected $fillable = ['section_id', 'position', 'heading', 'markdown_table', 'source']; protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/TextBlock.php b/apps/backend/app/Models/TextBlock.php index fae22fb..131ae19 100644 --- a/apps/backend/app/Models/TextBlock.php +++ b/apps/backend/app/Models/TextBlock.php @@ -11,13 +11,7 @@ class TextBlock extends Model /** @use HasFactory<\Database\Factories\TextBlockFactory> */ use HasFactory; - protected $fillable = [ - 'section_id', - 'position', - 'heading', - 'text', - 'source', - ]; + protected $fillable = ['section_id', 'position', 'heading', 'text', 'source']; protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/TimeBlock.php b/apps/backend/app/Models/TimeBlock.php index 519c9d8..fbb73cb 100644 --- a/apps/backend/app/Models/TimeBlock.php +++ b/apps/backend/app/Models/TimeBlock.php @@ -11,13 +11,7 @@ class TimeBlock extends Model /** @use HasFactory<\Database\Factories\TimeBlockFactory> */ use HasFactory; - protected $fillable = [ - 'project_id', - 'description', - 'is_chore', - 'start_time', - 'end_time', - ]; + protected $fillable = ['project_id', 'description', 'is_chore', 'start_time', 'end_time']; protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/User.php b/apps/backend/app/Models/User.php index 5b89e63..25de6d4 100644 --- a/apps/backend/app/Models/User.php +++ b/apps/backend/app/Models/User.php @@ -27,17 +27,9 @@ protected static function booted() }); } - protected $fillable = [ - 'first_name', - 'last_name', - 'email', - 'password', - ]; - - protected $hidden = [ - 'password', - 'remember_token', - ]; + protected $fillable = ['first_name', 'last_name', 'email', 'password']; + + protected $hidden = ['password', 'remember_token']; protected function casts() { diff --git a/apps/backend/app/Models/UserMeta.php b/apps/backend/app/Models/UserMeta.php index ffad010..d47c758 100644 --- a/apps/backend/app/Models/UserMeta.php +++ b/apps/backend/app/Models/UserMeta.php @@ -11,11 +11,7 @@ class UserMeta extends Model /** @use HasFactory<\Database\Factories\UserMetaFactory> */ use HasFactory; - protected $fillable = [ - 'user_id', - 'meta_key', - 'meta_value', - ]; + protected $fillable = ['user_id', 'meta_key', 'meta_value']; protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/UserSubCriterion.php b/apps/backend/app/Models/UserSubCriterion.php index b7b94b9..8b29eb3 100644 --- a/apps/backend/app/Models/UserSubCriterion.php +++ b/apps/backend/app/Models/UserSubCriterion.php @@ -11,11 +11,7 @@ class UserSubCriterion extends Model /** @use HasFactory<\Database\Factories\UserSubCriterionFactory> */ use HasFactory; - protected $fillable = [ - 'sub_criteria_id', - 'user_id', - 'is_fulfilled', - ]; + protected $fillable = ['sub_criteria_id', 'user_id', 'is_fulfilled']; protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/app/Models/Year.php b/apps/backend/app/Models/Year.php index 9f9e06b..63f72f2 100644 --- a/apps/backend/app/Models/Year.php +++ b/apps/backend/app/Models/Year.php @@ -11,10 +11,7 @@ class Year extends Model /** @use HasFactory<\Database\Factories\YearFactory> */ use HasFactory; - protected $fillable = [ - 'year', - 'is_active', - ]; + protected $fillable = ['year', 'is_active']; protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/bootstrap/app.php b/apps/backend/bootstrap/app.php index 8b8f233..8cfa27e 100644 --- a/apps/backend/bootstrap/app.php +++ b/apps/backend/bootstrap/app.php @@ -8,9 +8,9 @@ return Application::configure(basePath: dirname(__DIR__)) ->withRouting( - web: __DIR__.'/../routes/web.php', - api: __DIR__.'/../routes/api.php', - commands: __DIR__.'/../routes/console.php', + web: __DIR__ . '/../routes/web.php', + api: __DIR__ . '/../routes/api.php', + commands: __DIR__ . '/../routes/console.php', health: '/up', ) ->withMiddleware(function (Middleware $middleware): void { @@ -18,9 +18,11 @@ }) ->withExceptions(function (Exceptions $exceptions): void { // - }) ->withMiddleware(function (Middleware $middleware) { + }) + ->withMiddleware(function (Middleware $middleware) { // $middleware->alias([ - 'jwt' => JwtMiddleware::class + 'jwt' => JwtMiddleware::class, ]); - })->create(); + }) + ->create(); diff --git a/apps/backend/bootstrap/providers.php b/apps/backend/bootstrap/providers.php index 38b258d..2bd0b5c 100644 --- a/apps/backend/bootstrap/providers.php +++ b/apps/backend/bootstrap/providers.php @@ -1,5 +1,3 @@ env('APP_KEY'), - 'previous_keys' => [ - ...array_filter( - explode(',', (string) env('APP_PREVIOUS_KEYS', '')) - ), - ], + 'previous_keys' => [...array_filter(explode(',', (string) env('APP_PREVIOUS_KEYS', '')))], /* |-------------------------------------------------------------------------- @@ -122,5 +117,4 @@ 'driver' => env('APP_MAINTENANCE_DRIVER', 'file'), 'store' => env('APP_MAINTENANCE_STORE', 'database'), ], - ]; diff --git a/apps/backend/config/auth.php b/apps/backend/config/auth.php index 368c2f4..7cf9d71 100644 --- a/apps/backend/config/auth.php +++ b/apps/backend/config/auth.php @@ -1,7 +1,6 @@ env('AUTH_PASSWORD_TIMEOUT', 10800), - ]; diff --git a/apps/backend/config/cache.php b/apps/backend/config/cache.php index c2d927d..3fff2e2 100644 --- a/apps/backend/config/cache.php +++ b/apps/backend/config/cache.php @@ -3,7 +3,6 @@ use Illuminate\Support\Str; return [ - /* |-------------------------------------------------------------------------- | Default Cache Store @@ -32,7 +31,6 @@ */ 'stores' => [ - 'array' => [ 'driver' => 'array', 'serialize' => false, @@ -55,10 +53,7 @@ 'memcached' => [ 'driver' => 'memcached', 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), - 'sasl' => [ - env('MEMCACHED_USERNAME'), - env('MEMCACHED_PASSWORD'), - ], + 'sasl' => [env('MEMCACHED_USERNAME'), env('MEMCACHED_PASSWORD')], 'options' => [ // Memcached::OPT_CONNECT_TIMEOUT => 2000, ], @@ -89,7 +84,6 @@ 'octane' => [ 'driver' => 'octane', ], - ], /* @@ -103,6 +97,5 @@ | */ - 'prefix' => env('CACHE_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-cache-'), - + 'prefix' => env('CACHE_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')) . '-cache-'), ]; diff --git a/apps/backend/config/database.php b/apps/backend/config/database.php index 53dcae0..6ba4961 100644 --- a/apps/backend/config/database.php +++ b/apps/backend/config/database.php @@ -3,7 +3,6 @@ use Illuminate\Support\Str; return [ - /* |-------------------------------------------------------------------------- | Default Database Connection Name @@ -30,7 +29,6 @@ */ 'connections' => [ - 'sqlite' => [ 'driver' => 'sqlite', 'url' => env('DB_URL'), @@ -58,9 +56,11 @@ 'prefix_indexes' => true, 'strict' => true, 'engine' => null, - 'options' => extension_loaded('pdo_mysql') ? array_filter([ - PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), - ]) : [], + 'options' => extension_loaded('pdo_mysql') + ? array_filter([ + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) + : [], ], 'mariadb' => [ @@ -78,9 +78,11 @@ 'prefix_indexes' => true, 'strict' => true, 'engine' => null, - 'options' => extension_loaded('pdo_mysql') ? array_filter([ - PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), - ]) : [], + 'options' => extension_loaded('pdo_mysql') + ? array_filter([ + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) + : [], ], 'pgsql' => [ @@ -112,7 +114,6 @@ // 'encrypt' => env('DB_ENCRYPT', 'yes'), // 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'), ], - ], /* @@ -143,12 +144,14 @@ */ 'redis' => [ - 'client' => env('REDIS_CLIENT', 'phpredis'), 'options' => [ 'cluster' => env('REDIS_CLUSTER', 'redis'), - 'prefix' => env('REDIS_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-database-'), + 'prefix' => env( + 'REDIS_PREFIX', + Str::slug((string) env('APP_NAME', 'laravel')) . '-database-', + ), 'persistent' => env('REDIS_PERSISTENT', false), ], @@ -177,7 +180,5 @@ 'backoff_base' => env('REDIS_BACKOFF_BASE', 100), 'backoff_cap' => env('REDIS_BACKOFF_CAP', 1000), ], - ], - ]; diff --git a/apps/backend/config/filesystems.php b/apps/backend/config/filesystems.php index 3d671bd..30e570e 100644 --- a/apps/backend/config/filesystems.php +++ b/apps/backend/config/filesystems.php @@ -1,7 +1,6 @@ [ - 'local' => [ 'driver' => 'local', 'root' => storage_path('app/private'), @@ -41,7 +39,7 @@ 'public' => [ 'driver' => 'local', 'root' => storage_path('app/public'), - 'url' => env('APP_URL').'/storage', + 'url' => env('APP_URL') . '/storage', 'visibility' => 'public', 'throw' => false, 'report' => false, @@ -59,7 +57,6 @@ 'throw' => false, 'report' => false, ], - ], /* @@ -76,5 +73,4 @@ 'links' => [ public_path('storage') => storage_path('app/public'), ], - ]; diff --git a/apps/backend/config/jwt.php b/apps/backend/config/jwt.php index f83234d..844d769 100644 --- a/apps/backend/config/jwt.php +++ b/apps/backend/config/jwt.php @@ -10,7 +10,6 @@ */ return [ - /* |-------------------------------------------------------------------------- | JWT Authentication Secret @@ -45,7 +44,6 @@ */ 'keys' => [ - /* |-------------------------------------------------------------------------- | Public Key @@ -82,7 +80,6 @@ */ 'passphrase' => env('JWT_PASSPHRASE'), - ], /* @@ -144,14 +141,7 @@ | */ - 'required_claims' => [ - 'iss', - 'iat', - 'exp', - 'nbf', - 'sub', - 'jti', - ], + 'required_claims' => ['iss', 'iat', 'exp', 'nbf', 'sub', 'jti'], /* |-------------------------------------------------------------------------- @@ -262,7 +252,6 @@ */ 'providers' => [ - /* |-------------------------------------------------------------------------- | JWT Provider @@ -295,7 +284,5 @@ */ 'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class, - ], - ]; diff --git a/apps/backend/config/logging.php b/apps/backend/config/logging.php index 9e998a4..6fbe654 100644 --- a/apps/backend/config/logging.php +++ b/apps/backend/config/logging.php @@ -6,7 +6,6 @@ use Monolog\Processor\PsrLogMessageProcessor; return [ - /* |-------------------------------------------------------------------------- | Default Log Channel @@ -51,7 +50,6 @@ */ 'channels' => [ - 'stack' => [ 'driver' => 'stack', 'channels' => explode(',', (string) env('LOG_STACK', 'single')), @@ -89,7 +87,8 @@ 'handler_with' => [ 'host' => env('PAPERTRAIL_URL'), 'port' => env('PAPERTRAIL_PORT'), - 'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'), + 'connectionString' => + 'tls://' . env('PAPERTRAIL_URL') . ':' . env('PAPERTRAIL_PORT'), ], 'processors' => [PsrLogMessageProcessor::class], ], @@ -126,7 +125,5 @@ 'emergency' => [ 'path' => storage_path('logs/laravel.log'), ], - ], - ]; diff --git a/apps/backend/config/mail.php b/apps/backend/config/mail.php index 522b284..c22ccf6 100644 --- a/apps/backend/config/mail.php +++ b/apps/backend/config/mail.php @@ -1,7 +1,6 @@ [ - 'smtp' => [ 'transport' => 'smtp', 'scheme' => env('MAIL_SCHEME'), @@ -46,7 +44,10 @@ 'username' => env('MAIL_USERNAME'), 'password' => env('MAIL_PASSWORD'), 'timeout' => null, - 'local_domain' => env('MAIL_EHLO_DOMAIN', parse_url((string) env('APP_URL', 'http://localhost'), PHP_URL_HOST)), + 'local_domain' => env( + 'MAIL_EHLO_DOMAIN', + parse_url((string) env('APP_URL', 'http://localhost'), PHP_URL_HOST), + ), ], 'ses' => [ @@ -81,22 +82,15 @@ 'failover' => [ 'transport' => 'failover', - 'mailers' => [ - 'smtp', - 'log', - ], + 'mailers' => ['smtp', 'log'], 'retry_after' => 60, ], 'roundrobin' => [ 'transport' => 'roundrobin', - 'mailers' => [ - 'ses', - 'postmark', - ], + 'mailers' => ['ses', 'postmark'], 'retry_after' => 60, ], - ], /* @@ -114,5 +108,4 @@ 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), 'name' => env('MAIL_FROM_NAME', 'Example'), ], - ]; diff --git a/apps/backend/config/queue.php b/apps/backend/config/queue.php index 116bd8d..ee2f2d0 100644 --- a/apps/backend/config/queue.php +++ b/apps/backend/config/queue.php @@ -1,7 +1,6 @@ [ - 'sync' => [ 'driver' => 'sync', ], @@ -71,7 +69,6 @@ 'block_for' => null, 'after_commit' => false, ], - ], /* @@ -108,5 +105,4 @@ 'database' => env('DB_CONNECTION', 'sqlite'), 'table' => 'failed_jobs', ], - ]; diff --git a/apps/backend/config/sanctum.php b/apps/backend/config/sanctum.php index 44527d6..30b36d5 100644 --- a/apps/backend/config/sanctum.php +++ b/apps/backend/config/sanctum.php @@ -3,7 +3,6 @@ use Laravel\Sanctum\Sanctum; return [ - /* |-------------------------------------------------------------------------- | Stateful Domains @@ -15,12 +14,18 @@ | */ - 'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( - '%s%s', - 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', - Sanctum::currentApplicationUrlWithPort(), - // Sanctum::currentRequestHost(), - ))), + 'stateful' => explode( + ',', + env( + 'SANCTUM_STATEFUL_DOMAINS', + sprintf( + '%s%s', + 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', + Sanctum::currentApplicationUrlWithPort(), + // Sanctum::currentRequestHost(), + ), + ), + ), /* |-------------------------------------------------------------------------- @@ -80,5 +85,4 @@ 'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class, 'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class, ], - ]; diff --git a/apps/backend/config/services.php b/apps/backend/config/services.php index 6182e4b..2f2284f 100644 --- a/apps/backend/config/services.php +++ b/apps/backend/config/services.php @@ -1,7 +1,6 @@ env('SLACK_BOT_USER_DEFAULT_CHANNEL'), ], ], - ]; diff --git a/apps/backend/config/session.php b/apps/backend/config/session.php index bc45901..e7719ed 100644 --- a/apps/backend/config/session.php +++ b/apps/backend/config/session.php @@ -3,7 +3,6 @@ use Illuminate\Support\Str; return [ - /* |-------------------------------------------------------------------------- | Default Session Driver @@ -127,10 +126,7 @@ | */ - 'cookie' => env( - 'SESSION_COOKIE', - Str::slug((string) env('APP_NAME', 'laravel')).'-session' - ), + 'cookie' => env('SESSION_COOKIE', Str::slug((string) env('APP_NAME', 'laravel')) . '-session'), /* |-------------------------------------------------------------------------- @@ -213,5 +209,4 @@ */ 'partitioned' => env('SESSION_PARTITIONED_COOKIE', false), - ]; diff --git a/apps/backend/database/factories/TableFactory.php b/apps/backend/database/factories/TableFactory.php index 0abd005..3ce0404 100644 --- a/apps/backend/database/factories/TableFactory.php +++ b/apps/backend/database/factories/TableFactory.php @@ -29,7 +29,8 @@ public function definition(): array 'section_id' => Section::factory(), 'position' => $this->faker->numberBetween(1, 10), 'heading' => $this->faker->sentence(3), - 'markdown_table' => '| Header 1 | Header 2 |\n|----------|----------|\n| Cell 1 | Cell 2 |', + 'markdown_table' => + '| Header 1 | Header 2 |\n|----------|----------|\n| Cell 1 | Cell 2 |', 'source' => $this->faker->url(), ]; } diff --git a/apps/backend/database/factories/UserFactory.php b/apps/backend/database/factories/UserFactory.php index 61026e8..56ab8e8 100644 --- a/apps/backend/database/factories/UserFactory.php +++ b/apps/backend/database/factories/UserFactory.php @@ -27,9 +27,8 @@ public function definition(): array 'first_name' => fake()->firstName(), 'last_name' => fake()->lastName(), 'email' => fake()->unique()->safeEmail(), - 'password' => static::$password ??= Hash::make('password'), + 'password' => (static::$password ??= Hash::make('password')), 'remember_token' => Str::random(10), ]; } - } diff --git a/apps/backend/database/migrations/0001_01_01_000000_create_users_table.php b/apps/backend/database/migrations/0001_01_01_000000_create_users_table.php index de2c40f..47689cc 100644 --- a/apps/backend/database/migrations/0001_01_01_000000_create_users_table.php +++ b/apps/backend/database/migrations/0001_01_01_000000_create_users_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/apps/backend/database/migrations/0001_01_01_000001_create_cache_table.php b/apps/backend/database/migrations/0001_01_01_000001_create_cache_table.php index b9c106b..1d3e5b4 100644 --- a/apps/backend/database/migrations/0001_01_01_000001_create_cache_table.php +++ b/apps/backend/database/migrations/0001_01_01_000001_create_cache_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/apps/backend/database/migrations/0001_01_01_000002_create_jobs_table.php b/apps/backend/database/migrations/0001_01_01_000002_create_jobs_table.php index 425e705..f3e3e2d 100644 --- a/apps/backend/database/migrations/0001_01_01_000002_create_jobs_table.php +++ b/apps/backend/database/migrations/0001_01_01_000002_create_jobs_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/apps/backend/database/migrations/01_2025_10_03_225024_create_years_table.php b/apps/backend/database/migrations/01_2025_10_03_225024_create_years_table.php index 72e399e..a6af485 100644 --- a/apps/backend/database/migrations/01_2025_10_03_225024_create_years_table.php +++ b/apps/backend/database/migrations/01_2025_10_03_225024_create_years_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/apps/backend/database/migrations/02_2025_10_03_225024_create_projects_table.php b/apps/backend/database/migrations/02_2025_10_03_225024_create_projects_table.php index 0e5343b..3fc5480 100644 --- a/apps/backend/database/migrations/02_2025_10_03_225024_create_projects_table.php +++ b/apps/backend/database/migrations/02_2025_10_03_225024_create_projects_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/apps/backend/database/migrations/03_2025_10_03_225025_create_chapters_table.php b/apps/backend/database/migrations/03_2025_10_03_225025_create_chapters_table.php index 6f9c764..c7f42fd 100644 --- a/apps/backend/database/migrations/03_2025_10_03_225025_create_chapters_table.php +++ b/apps/backend/database/migrations/03_2025_10_03_225025_create_chapters_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/apps/backend/database/migrations/04_2025_10_03_225025_create_sections_table.php b/apps/backend/database/migrations/04_2025_10_03_225025_create_sections_table.php index 6a82355..c63ddf0 100644 --- a/apps/backend/database/migrations/04_2025_10_03_225025_create_sections_table.php +++ b/apps/backend/database/migrations/04_2025_10_03_225025_create_sections_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/apps/backend/database/migrations/2025_10_03_221436_create_personal_access_tokens_table.php b/apps/backend/database/migrations/2025_10_03_221436_create_personal_access_tokens_table.php index 40ff706..4279a2e 100644 --- a/apps/backend/database/migrations/2025_10_03_221436_create_personal_access_tokens_table.php +++ b/apps/backend/database/migrations/2025_10_03_221436_create_personal_access_tokens_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/apps/backend/database/migrations/2025_10_03_225024_create_criteria_table.php b/apps/backend/database/migrations/2025_10_03_225024_create_criteria_table.php index 673cea4..ae1a02d 100644 --- a/apps/backend/database/migrations/2025_10_03_225024_create_criteria_table.php +++ b/apps/backend/database/migrations/2025_10_03_225024_create_criteria_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/apps/backend/database/migrations/2025_10_03_225024_create_glossaries_table.php b/apps/backend/database/migrations/2025_10_03_225024_create_glossaries_table.php index 21e3ad1..880709d 100644 --- a/apps/backend/database/migrations/2025_10_03_225024_create_glossaries_table.php +++ b/apps/backend/database/migrations/2025_10_03_225024_create_glossaries_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/apps/backend/database/migrations/2025_10_03_225024_create_sub_criteria_table.php b/apps/backend/database/migrations/2025_10_03_225024_create_sub_criteria_table.php index 00b9964..4d7cb99 100644 --- a/apps/backend/database/migrations/2025_10_03_225024_create_sub_criteria_table.php +++ b/apps/backend/database/migrations/2025_10_03_225024_create_sub_criteria_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/apps/backend/database/migrations/2025_10_03_225024_create_time_blocks_table.php b/apps/backend/database/migrations/2025_10_03_225024_create_time_blocks_table.php index bfe3397..290ed32 100644 --- a/apps/backend/database/migrations/2025_10_03_225024_create_time_blocks_table.php +++ b/apps/backend/database/migrations/2025_10_03_225024_create_time_blocks_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/apps/backend/database/migrations/2025_10_03_225024_create_user_metas_table.php b/apps/backend/database/migrations/2025_10_03_225024_create_user_metas_table.php index 21812ad..13d76bb 100644 --- a/apps/backend/database/migrations/2025_10_03_225024_create_user_metas_table.php +++ b/apps/backend/database/migrations/2025_10_03_225024_create_user_metas_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/apps/backend/database/migrations/2025_10_03_225024_create_user_sub_criteria_table.php b/apps/backend/database/migrations/2025_10_03_225024_create_user_sub_criteria_table.php index 5b84841..f346b54 100644 --- a/apps/backend/database/migrations/2025_10_03_225024_create_user_sub_criteria_table.php +++ b/apps/backend/database/migrations/2025_10_03_225024_create_user_sub_criteria_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/apps/backend/database/migrations/2025_10_03_225025_create_ai_ratings_table.php b/apps/backend/database/migrations/2025_10_03_225025_create_ai_ratings_table.php index a5e38e3..71e0c05 100644 --- a/apps/backend/database/migrations/2025_10_03_225025_create_ai_ratings_table.php +++ b/apps/backend/database/migrations/2025_10_03_225025_create_ai_ratings_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/apps/backend/database/migrations/2025_10_03_225025_create_images_table.php b/apps/backend/database/migrations/2025_10_03_225025_create_images_table.php index cee7ac1..816e117 100644 --- a/apps/backend/database/migrations/2025_10_03_225025_create_images_table.php +++ b/apps/backend/database/migrations/2025_10_03_225025_create_images_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/apps/backend/database/migrations/2025_10_03_225025_create_tables_table.php b/apps/backend/database/migrations/2025_10_03_225025_create_tables_table.php index 1a8a1c8..7d50104 100644 --- a/apps/backend/database/migrations/2025_10_03_225025_create_tables_table.php +++ b/apps/backend/database/migrations/2025_10_03_225025_create_tables_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/apps/backend/database/migrations/2025_10_03_225025_create_text_blocks_table.php b/apps/backend/database/migrations/2025_10_03_225025_create_text_blocks_table.php index 6a6dd58..ef61c21 100644 --- a/apps/backend/database/migrations/2025_10_03_225025_create_text_blocks_table.php +++ b/apps/backend/database/migrations/2025_10_03_225025_create_text_blocks_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php b/apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php index d577463..2970488 100644 --- a/apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php +++ b/apps/backend/database/migrations/2025_10_04_014456_create_permission_tables.php @@ -5,8 +5,7 @@ use Illuminate\Support\Facades\Schema; use Illuminate\Database\Query\Expression; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ @@ -18,27 +17,41 @@ public function up(): void $pivotRole = $columnNames['role_pivot_key'] ?? 'role_id'; $pivotPermission = $columnNames['permission_pivot_key'] ?? 'permission_id'; - throw_if(empty($tableNames), new Exception('Error: config/permission.php not loaded. Run [php artisan config:clear] and try again.')); - throw_if($teams && empty($columnNames['team_foreign_key'] ?? null), new Exception('Error: team_foreign_key on config/permission.php not loaded. Run [php artisan config:clear] and try again.')); + throw_if( + empty($tableNames), + new Exception( + 'Error: config/permission.php not loaded. Run [php artisan config:clear] and try again.', + ), + ); + throw_if( + $teams && empty($columnNames['team_foreign_key'] ?? null), + new Exception( + 'Error: team_foreign_key on config/permission.php not loaded. Run [php artisan config:clear] and try again.', + ), + ); Schema::create($tableNames['permissions'], static function (Blueprint $table) { // $table->engine('InnoDB'); $table->uuid('id')->primary()->default(new Expression('(UUID())')); - $table->string('name'); // For MyISAM use string('name', 225); // (or 166 for InnoDB with Redundant/Compact row format) + $table->string('name'); // For MyISAM use string('name', 225); // (or 166 for InnoDB with Redundant/Compact row format) $table->string('guard_name'); // For MyISAM use string('guard_name', 25); $table->timestamps(); $table->unique(['name', 'guard_name']); }); - Schema::create($tableNames['roles'], static function (Blueprint $table) use ($teams, $columnNames) { + Schema::create($tableNames['roles'], static function (Blueprint $table) use ( + $teams, + $columnNames, + ) { // $table->engine('InnoDB'); $table->uuid('id')->primary()->default(new Expression('(UUID())')); - if ($teams || config('permission.testing')) { // permission.testing is a fix for sqlite testing + if ($teams || config('permission.testing')) { + // permission.testing is a fix for sqlite testing $table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable(); $table->index($columnNames['team_foreign_key'], 'roles_team_foreign_key_index'); } - $table->string('name'); // For MyISAM use string('name', 225); // (or 166 for InnoDB with Redundant/Compact row format) + $table->string('name'); // For MyISAM use string('name', 225); // (or 166 for InnoDB with Redundant/Compact row format) $table->string('guard_name'); // For MyISAM use string('guard_name', 25); $table->timestamps(); if ($teams || config('permission.testing')) { @@ -48,71 +61,122 @@ public function up(): void } }); - Schema::create($tableNames['model_has_permissions'], static function (Blueprint $table) use ($tableNames, $columnNames, $pivotPermission, $teams) { + Schema::create($tableNames['model_has_permissions'], static function ( + Blueprint $table, + ) use ($tableNames, $columnNames, $pivotPermission, $teams) { $table->uuid($pivotPermission); $table->string('model_type'); $table->uuid($columnNames['model_morph_key']); - $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index'); + $table->index( + [$columnNames['model_morph_key'], 'model_type'], + 'model_has_permissions_model_id_model_type_index', + ); - $table->foreign($pivotPermission) + $table + ->foreign($pivotPermission) ->references('id') ->on($tableNames['permissions']) ->onDelete('cascade'); if ($teams) { $table->unsignedBigInteger($columnNames['team_foreign_key']); - $table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index'); - - $table->primary([$columnNames['team_foreign_key'], $pivotPermission, $columnNames['model_morph_key'], 'model_type'], - 'model_has_permissions_permission_model_type_primary'); + $table->index( + $columnNames['team_foreign_key'], + 'model_has_permissions_team_foreign_key_index', + ); + + $table->primary( + [ + $columnNames['team_foreign_key'], + $pivotPermission, + $columnNames['model_morph_key'], + 'model_type', + ], + 'model_has_permissions_permission_model_type_primary', + ); } else { - $table->primary([$pivotPermission, $columnNames['model_morph_key'], 'model_type'], - 'model_has_permissions_permission_model_type_primary'); + $table->primary( + [$pivotPermission, $columnNames['model_morph_key'], 'model_type'], + 'model_has_permissions_permission_model_type_primary', + ); } - }); - Schema::create($tableNames['model_has_roles'], static function (Blueprint $table) use ($tableNames, $columnNames, $pivotRole, $teams) { + Schema::create($tableNames['model_has_roles'], static function (Blueprint $table) use ( + $tableNames, + $columnNames, + $pivotRole, + $teams, + ) { $table->uuid($pivotRole); $table->string('model_type'); $table->uuid($columnNames['model_morph_key']); - $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index'); + $table->index( + [$columnNames['model_morph_key'], 'model_type'], + 'model_has_roles_model_id_model_type_index', + ); - $table->foreign($pivotRole) + $table + ->foreign($pivotRole) ->references('id') // role id ->on($tableNames['roles']) ->onDelete('cascade'); if ($teams) { $table->unsignedBigInteger($columnNames['team_foreign_key']); - $table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index'); - - $table->primary([$columnNames['team_foreign_key'], $pivotRole, $columnNames['model_morph_key'], 'model_type'], - 'model_has_roles_role_model_type_primary'); + $table->index( + $columnNames['team_foreign_key'], + 'model_has_roles_team_foreign_key_index', + ); + + $table->primary( + [ + $columnNames['team_foreign_key'], + $pivotRole, + $columnNames['model_morph_key'], + 'model_type', + ], + 'model_has_roles_role_model_type_primary', + ); } else { - $table->primary([$pivotRole, $columnNames['model_morph_key'], 'model_type'], - 'model_has_roles_role_model_type_primary'); + $table->primary( + [$pivotRole, $columnNames['model_morph_key'], 'model_type'], + 'model_has_roles_role_model_type_primary', + ); } }); - Schema::create($tableNames['role_has_permissions'], static function (Blueprint $table) use ($tableNames, $pivotRole, $pivotPermission) { + Schema::create($tableNames['role_has_permissions'], static function (Blueprint $table) use ( + $tableNames, + $pivotRole, + $pivotPermission, + ) { $table->uuid($pivotPermission); $table->uuid($pivotRole); - $table->foreign($pivotPermission) + $table + ->foreign($pivotPermission) ->references('id') // permission id ->on($tableNames['permissions']) ->onDelete('cascade'); - $table->foreign($pivotRole) + $table + ->foreign($pivotRole) ->references('id') // role id ->on($tableNames['roles']) ->onDelete('cascade'); - $table->primary([$pivotPermission, $pivotRole], 'role_has_permissions_permission_id_role_id_primary'); + $table->primary( + [$pivotPermission, $pivotRole], + 'role_has_permissions_permission_id_role_id_primary', + ); }); app('cache') - ->store(config('permission.cache.store') != 'default' ? config('permission.cache.store') : null) + ->store( + config('permission.cache.store') != 'default' + ? config('permission.cache.store') + : null, + ) ->forget(config('permission.cache.key')); } @@ -124,7 +188,9 @@ public function down(): void $tableNames = config('permission.table_names'); if (empty($tableNames)) { - throw new \Exception('Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.'); + throw new \Exception( + 'Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.', + ); } Schema::drop($tableNames['role_has_permissions']); diff --git a/apps/backend/database/migrations/2025_10_04_021216_create_roles_and_permissions.php b/apps/backend/database/migrations/2025_10_04_021216_create_roles_and_permissions.php index 37e9174..80cfefd 100644 --- a/apps/backend/database/migrations/2025_10_04_021216_create_roles_and_permissions.php +++ b/apps/backend/database/migrations/2025_10_04_021216_create_roles_and_permissions.php @@ -2,8 +2,7 @@ use Illuminate\Database\Migrations\Migration; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ @@ -29,16 +28,26 @@ public function up(): void $manage_criteria = \App\Models\Permission::create(['name' => 'manage criteria']); $apprentice_role->givePermissionTo($edit_projects, $view_criteria); - $mentor_role->givePermissionTo($create_projects, $view_projects, $view_users, $view_years, $view_criteria, $manage_criteria); - $supervisor_role->givePermissionTo($manage_projects, $view_users, $manage_years, $manage_criteria, $manage_years); + $mentor_role->givePermissionTo( + $create_projects, + $view_projects, + $view_users, + $view_years, + $view_criteria, + $manage_criteria, + ); + $supervisor_role->givePermissionTo( + $manage_projects, + $view_users, + $manage_years, + $manage_criteria, + $manage_years, + ); $admin_role->givePermissionTo(\App\Models\Permission::all()); } /** * Reverse the migrations. */ - public function down(): void - { - - } + public function down(): void {} }; diff --git a/apps/backend/database/seeders/DatabaseSeeder.php b/apps/backend/database/seeders/DatabaseSeeder.php index ac75561..b9acee6 100644 --- a/apps/backend/database/seeders/DatabaseSeeder.php +++ b/apps/backend/database/seeders/DatabaseSeeder.php @@ -3,7 +3,23 @@ namespace Database\Seeders; use Illuminate\Database\Seeder; -use App\Models\{Year, User, Project, Chapter, Section, TextBlock, Table as TableModel, Image, AiRating, Glossary, Criterion, SubCriterion, TimeBlock, UserMeta, UserSubCriterion}; +use App\Models\{ + Year, + User, + Project, + Chapter, + Section, + TextBlock, + Table as TableModel, + Image, + AiRating, + Glossary, + Criterion, + SubCriterion, + TimeBlock, + UserMeta, + UserSubCriterion, +}; class DatabaseSeeder extends Seeder { @@ -17,80 +33,119 @@ public function run(): void $users = User::factory()->count(rand(5, 10))->create(); // Projects linked to existing Years and Users - $projects = Project::factory()->count(rand(5, 10))->make()->each(function (Project $project) use ($years, $users) { - $project->year_id = $years->random()->id; - $project->owner_id = $users->random()->id; - $project->save(); - }); + $projects = Project::factory() + ->count(rand(5, 10)) + ->make() + ->each(function (Project $project) use ($years, $users) { + $project->year_id = $years->random()->id; + $project->owner_id = $users->random()->id; + $project->save(); + }); // Chapters linked to Projects - $chapters = Chapter::factory()->count(rand(5, 10))->make()->each(function (Chapter $chapter) use ($projects) { - $chapter->project_id = $projects->random()->id; - $chapter->save(); - }); + $chapters = Chapter::factory() + ->count(rand(5, 10)) + ->make() + ->each(function (Chapter $chapter) use ($projects) { + $chapter->project_id = $projects->random()->id; + $chapter->save(); + }); // Sections linked to Chapters - $sections = Section::factory()->count(rand(5, 10))->make()->each(function (Section $section) use ($chapters) { - $section->chapter_id = $chapters->random()->id; - $section->parent_id = null; - $section->save(); - }); + $sections = Section::factory() + ->count(rand(5, 10)) + ->make() + ->each(function (Section $section) use ($chapters) { + $section->chapter_id = $chapters->random()->id; + $section->parent_id = null; + $section->save(); + }); // Content linked to Sections - TextBlock::factory()->count(rand(5, 10))->make()->each(function (TextBlock $tb) use ($sections) { - $tb->section_id = $sections->random()->id; - $tb->save(); - }); - - TableModel::factory()->count(rand(5, 10))->make()->each(function (TableModel $tbl) use ($sections) { - $tbl->section_id = $sections->random()->id; - $tbl->save(); - }); - - Image::factory()->count(rand(5, 10))->make()->each(function (Image $img) use ($sections) { - $img->section_id = $sections->random()->id; - $img->save(); - }); - - AiRating::factory()->count(rand(5, 10))->make()->each(function (AiRating $r) use ($sections) { - $r->section_id = $sections->random()->id; - $r->save(); - }); + TextBlock::factory() + ->count(rand(5, 10)) + ->make() + ->each(function (TextBlock $tb) use ($sections) { + $tb->section_id = $sections->random()->id; + $tb->save(); + }); + + TableModel::factory() + ->count(rand(5, 10)) + ->make() + ->each(function (TableModel $tbl) use ($sections) { + $tbl->section_id = $sections->random()->id; + $tbl->save(); + }); + + Image::factory() + ->count(rand(5, 10)) + ->make() + ->each(function (Image $img) use ($sections) { + $img->section_id = $sections->random()->id; + $img->save(); + }); + + AiRating::factory() + ->count(rand(5, 10)) + ->make() + ->each(function (AiRating $r) use ($sections) { + $r->section_id = $sections->random()->id; + $r->save(); + }); // Glossary terms linked to Projects - Glossary::factory()->count(rand(5, 10))->make()->each(function (Glossary $g) use ($projects) { - $g->project_id = $projects->random()->id; - $g->save(); - }); + Glossary::factory() + ->count(rand(5, 10)) + ->make() + ->each(function (Glossary $g) use ($projects) { + $g->project_id = $projects->random()->id; + $g->save(); + }); // Criteria and SubCriteria linked to Years/Criteria - $criteria = Criterion::factory()->count(rand(5, 10))->make()->each(function (Criterion $c) use ($years) { - $c->year_id = $years->random()->id; - $c->special_for_project_id = null; - $c->save(); - }); - - $subCriteria = SubCriterion::factory()->count(rand(5, 10))->make()->each(function (SubCriterion $sc) use ($criteria) { - $sc->criteria_id = $criteria->random()->id; - $sc->save(); - }); + $criteria = Criterion::factory() + ->count(rand(5, 10)) + ->make() + ->each(function (Criterion $c) use ($years) { + $c->year_id = $years->random()->id; + $c->special_for_project_id = null; + $c->save(); + }); + + $subCriteria = SubCriterion::factory() + ->count(rand(5, 10)) + ->make() + ->each(function (SubCriterion $sc) use ($criteria) { + $sc->criteria_id = $criteria->random()->id; + $sc->save(); + }); // Time tracking linked to Projects - TimeBlock::factory()->count(rand(5, 10))->make()->each(function (TimeBlock $tb) use ($projects) { - $tb->project_id = $projects->random()->id; - $tb->save(); - }); + TimeBlock::factory() + ->count(rand(5, 10)) + ->make() + ->each(function (TimeBlock $tb) use ($projects) { + $tb->project_id = $projects->random()->id; + $tb->save(); + }); // User meta and user-sub-criteria - UserMeta::factory()->count(rand(5, 10))->make()->each(function (UserMeta $um) use ($users) { - $um->user_id = $users->random()->id; - $um->save(); - }); - - UserSubCriterion::factory()->count(rand(5, 10))->make()->each(function (UserSubCriterion $usc) use ($users, $subCriteria) { - $usc->user_id = $users->random()->id; - $usc->sub_criteria_id = $subCriteria->random()->id; - $usc->save(); - }); + UserMeta::factory() + ->count(rand(5, 10)) + ->make() + ->each(function (UserMeta $um) use ($users) { + $um->user_id = $users->random()->id; + $um->save(); + }); + + UserSubCriterion::factory() + ->count(rand(5, 10)) + ->make() + ->each(function (UserSubCriterion $usc) use ($users, $subCriteria) { + $usc->user_id = $users->random()->id; + $usc->sub_criteria_id = $subCriteria->random()->id; + $usc->save(); + }); } } diff --git a/apps/backend/package-lock.json b/apps/backend/package-lock.json index 24a35c4..66a3b3e 100644 --- a/apps/backend/package-lock.json +++ b/apps/backend/package-lock.json @@ -5,10 +5,12 @@ "packages": { "": { "devDependencies": { + "@prettier/plugin-php": "^0.24.0", "@tailwindcss/vite": "^4.0.0", "axios": "^1.11.0", "concurrently": "^9.0.1", "laravel-vite-plugin": "^2.0.0", + "prettier": "^3.6.2", "tailwindcss": "^4.0.0", "vite": "^7.0.7" } @@ -518,6 +520,20 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@prettier/plugin-php": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@prettier/plugin-php/-/plugin-php-0.24.0.tgz", + "integrity": "sha512-x9l65fCE/pgoET6RQowgdgG8Xmzs44z6j6Hhg3coINCyCw9JBGJ5ZzMR2XHAM2jmAdbJAIgqB6cUn4/3W3XLTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "linguist-languages": "^8.0.0", + "php-parser": "^3.2.5" + }, + "peerDependencies": { + "prettier": "^3.0.0" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.52.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.4.tgz", @@ -1920,6 +1936,13 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/linguist-languages": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/linguist-languages/-/linguist-languages-8.2.0.tgz", + "integrity": "sha512-KCUUH9x97QWYU0SXOCGxUrZR6cSfuQrMhABB7L/0I8N0LXOeaKe7+RZs7FAwvWCV2qKfZ4Wv1luLq4OfMezSJg==", + "dev": true, + "license": "MIT" + }, "node_modules/magic-string": { "version": "0.30.19", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", @@ -2005,6 +2028,13 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/php-parser": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/php-parser/-/php-parser-3.2.5.tgz", + "integrity": "sha512-M1ZYlALFFnESbSdmRtTQrBFUHSriHgPhgqtTF/LCbZM4h7swR5PHtUceB2Kzby5CfqcsYwBn7OXTJ0+8Sajwkw==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -2054,6 +2084,22 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", diff --git a/apps/backend/package.json b/apps/backend/package.json index af0db45..0cea0b2 100644 --- a/apps/backend/package.json +++ b/apps/backend/package.json @@ -7,10 +7,12 @@ "dev": "vite" }, "devDependencies": { + "@prettier/plugin-php": "^0.24.0", "@tailwindcss/vite": "^4.0.0", "axios": "^1.11.0", "concurrently": "^9.0.1", "laravel-vite-plugin": "^2.0.0", + "prettier": "^3.6.2", "tailwindcss": "^4.0.0", "vite": "^7.0.7" } diff --git a/apps/backend/public/index.php b/apps/backend/public/index.php index ee8f07e..86bfe78 100644 --- a/apps/backend/public/index.php +++ b/apps/backend/public/index.php @@ -6,15 +6,15 @@ define('LARAVEL_START', microtime(true)); // Determine if the application is in maintenance mode... -if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) { +if (file_exists($maintenance = __DIR__ . '/../storage/framework/maintenance.php')) { require $maintenance; } // Register the Composer autoloader... -require __DIR__.'/../vendor/autoload.php'; +require __DIR__ . '/../vendor/autoload.php'; // Bootstrap Laravel and handle the request... /** @var Application $app */ -$app = require_once __DIR__.'/../bootstrap/app.php'; +$app = require_once __DIR__ . '/../bootstrap/app.php'; $app->handleRequest(Request::capture()); diff --git a/apps/backend/routes/api.php b/apps/backend/routes/api.php index 27668e7..e9b4268 100644 --- a/apps/backend/routes/api.php +++ b/apps/backend/routes/api.php @@ -5,7 +5,6 @@ use App\Http\Controllers\AuthController; use App\Http\Controllers\ProjectController; - Route::post('/register', [AuthController::class, 'register']); Route::post('/login', [AuthController::class, 'login']); @@ -16,14 +15,18 @@ Route::post('/logout', [AuthController::class, 'logout']); }); -Route::middleware('jwt')->prefix('project')->group(function () { - Route::post('/create', [ProjectController::class, 'createProject']); -}); +Route::middleware('jwt') + ->prefix('project') + ->group(function () { + Route::post('/create', [ProjectController::class, 'createProject']); + }); -Route::middleware('jwt')->prefix('year')->group(function () { - Route::get('/', [App\Http\Controllers\YearController::class, 'index']); - Route::get('/{id}', [App\Http\Controllers\YearController::class, 'show']); - Route::post('/', [App\Http\Controllers\YearController::class, 'store']); - Route::put('/{id}', [App\Http\Controllers\YearController::class, 'update']); - Route::delete('/{id}', [App\Http\Controllers\YearController::class, 'delete']); -}); +Route::middleware('jwt') + ->prefix('year') + ->group(function () { + Route::get('/', [App\Http\Controllers\YearController::class, 'index']); + Route::get('/{id}', [App\Http\Controllers\YearController::class, 'show']); + Route::post('/', [App\Http\Controllers\YearController::class, 'store']); + Route::put('/{id}', [App\Http\Controllers\YearController::class, 'update']); + Route::delete('/{id}', [App\Http\Controllers\YearController::class, 'delete']); + }); From ba36135c62b5a6d7847118030bcc7be0b0a93a1d Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 07:17:55 +0200 Subject: [PATCH 14/22] refactor: cleanup routes --- apps/backend/routes/console.php | 8 -------- apps/backend/routes/web.php | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) delete mode 100644 apps/backend/routes/console.php diff --git a/apps/backend/routes/console.php b/apps/backend/routes/console.php deleted file mode 100644 index 3c9adf1..0000000 --- a/apps/backend/routes/console.php +++ /dev/null @@ -1,8 +0,0 @@ -comment(Inspiring::quote()); -})->purpose('Display an inspiring quote'); diff --git a/apps/backend/routes/web.php b/apps/backend/routes/web.php index 86a06c5..c2ecb84 100644 --- a/apps/backend/routes/web.php +++ b/apps/backend/routes/web.php @@ -3,5 +3,5 @@ use Illuminate\Support\Facades\Route; Route::get('/', function () { - return view('welcome'); + return json_encode(['status' => 'ok']); }); From 5e050f197bb5f26f42de3e54d34bbb4ea54e267d Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 08:44:05 +0200 Subject: [PATCH 15/22] feat; implement all CRUD endpoints --- .../Http/Controllers/AiRatingController.php | 39 ++++++++++ .../app/Http/Controllers/AuthController.php | 13 +++- .../Http/Controllers/ChapterController.php | 39 ++++++++++ .../Http/Controllers/CriterionController.php | 39 ++++++++++ .../Http/Controllers/GlossariesController.php | 2 + .../Http/Controllers/GlossaryController.php | 39 ++++++++++ .../app/Http/Controllers/ImageController.php | 39 ++++++++++ .../Http/Controllers/PermissionController.php | 39 ++++++++++ .../Http/Controllers/ProjectController.php | 31 ++++++++ .../Controllers/ProjectCrudController.php | 39 ++++++++++ .../Http/Controllers/ProjectSController.php | 2 + .../app/Http/Controllers/RoleController.php | 39 ++++++++++ .../Http/Controllers/SectionController.php | 39 ++++++++++ .../Controllers/SubCriterionController.php | 39 ++++++++++ .../app/Http/Controllers/TableController.php | 39 ++++++++++ .../Http/Controllers/TextBlockController.php | 39 ++++++++++ .../Http/Controllers/TimeBlockController.php | 39 ++++++++++ .../app/Http/Controllers/UserController.php | 39 ++++++++++ .../Http/Controllers/UserMetaController.php | 39 ++++++++++ .../UserSubCriterionController.php | 39 ++++++++++ .../app/Http/Controllers/YearController.php | 11 +-- .../AiRating/StoreAiRatingRequest.php | 16 ++++ .../AiRating/UpdateAiRatingRequest.php | 16 ++++ .../Requests/Chapter/StoreChapterRequest.php | 16 ++++ .../Requests/Chapter/UpdateChapterRequest.php | 16 ++++ .../Criterion/StoreCriterionRequest.php | 16 ++++ .../Criterion/UpdateCriterionRequest.php | 16 ++++ .../Glossary/StoreGlossaryRequest.php | 15 ++++ .../Glossary/UpdateGlossaryRequest.php | 15 ++++ .../Http/Requests/Image/StoreImageRequest.php | 17 +++++ .../Requests/Image/UpdateImageRequest.php | 17 +++++ .../Permission/StorePermissionRequest.php | 14 ++++ .../Permission/UpdatePermissionRequest.php | 14 ++++ .../Requests/Project/StoreProjectRequest.php | 25 +++++++ .../Requests/Project/UpdateProjectRequest.php | 25 +++++++ .../Http/Requests/Role/StoreRoleRequest.php | 14 ++++ .../Http/Requests/Role/UpdateRoleRequest.php | 14 ++++ .../Requests/Section/StoreSectionRequest.php | 18 +++++ .../Requests/Section/UpdateSectionRequest.php | 18 +++++ .../SubCriterion/StoreSubCriterionRequest.php | 14 ++++ .../UpdateSubCriterionRequest.php | 14 ++++ .../Http/Requests/Table/StoreTableRequest.php | 17 +++++ .../Requests/Table/UpdateTableRequest.php | 17 +++++ .../TextBlock/StoreTextBlockRequest.php | 17 +++++ .../TextBlock/UpdateTextBlockRequest.php | 17 +++++ .../TimeBlock/StoreTimeBlockRequest.php | 17 +++++ .../TimeBlock/UpdateTimeBlockRequest.php | 17 +++++ .../Http/Requests/User/StoreUserRequest.php | 16 ++++ .../Http/Requests/User/UpdateUserRequest.php | 16 ++++ .../UserMeta/StoreUserMetaRequest.php | 15 ++++ .../UserMeta/UpdateUserMetaRequest.php | 15 ++++ .../StoreUserSubCriterionRequest.php | 15 ++++ .../UpdateUserSubCriterionRequest.php | 15 ++++ .../Http/Requests/Year/StoreYearRequest.php | 21 ++++++ .../Http/Requests/Year/UpdateYearRequest.php | 21 ++++++ apps/backend/app/Models/User.php | 3 +- .../database/seeders/DatabaseSeeder.php | 41 ++++++++++ apps/backend/routes/api.php | 74 +++++++++++++++---- 58 files changed, 1341 insertions(+), 26 deletions(-) create mode 100644 apps/backend/app/Http/Controllers/AiRatingController.php create mode 100644 apps/backend/app/Http/Controllers/ChapterController.php create mode 100644 apps/backend/app/Http/Controllers/CriterionController.php create mode 100644 apps/backend/app/Http/Controllers/GlossariesController.php create mode 100644 apps/backend/app/Http/Controllers/GlossaryController.php create mode 100644 apps/backend/app/Http/Controllers/ImageController.php create mode 100644 apps/backend/app/Http/Controllers/PermissionController.php create mode 100644 apps/backend/app/Http/Controllers/ProjectCrudController.php create mode 100644 apps/backend/app/Http/Controllers/ProjectSController.php create mode 100644 apps/backend/app/Http/Controllers/RoleController.php create mode 100644 apps/backend/app/Http/Controllers/SectionController.php create mode 100644 apps/backend/app/Http/Controllers/SubCriterionController.php create mode 100644 apps/backend/app/Http/Controllers/TableController.php create mode 100644 apps/backend/app/Http/Controllers/TextBlockController.php create mode 100644 apps/backend/app/Http/Controllers/TimeBlockController.php create mode 100644 apps/backend/app/Http/Controllers/UserController.php create mode 100644 apps/backend/app/Http/Controllers/UserMetaController.php create mode 100644 apps/backend/app/Http/Controllers/UserSubCriterionController.php create mode 100644 apps/backend/app/Http/Requests/AiRating/StoreAiRatingRequest.php create mode 100644 apps/backend/app/Http/Requests/AiRating/UpdateAiRatingRequest.php create mode 100644 apps/backend/app/Http/Requests/Chapter/StoreChapterRequest.php create mode 100644 apps/backend/app/Http/Requests/Chapter/UpdateChapterRequest.php create mode 100644 apps/backend/app/Http/Requests/Criterion/StoreCriterionRequest.php create mode 100644 apps/backend/app/Http/Requests/Criterion/UpdateCriterionRequest.php create mode 100644 apps/backend/app/Http/Requests/Glossary/StoreGlossaryRequest.php create mode 100644 apps/backend/app/Http/Requests/Glossary/UpdateGlossaryRequest.php create mode 100644 apps/backend/app/Http/Requests/Image/StoreImageRequest.php create mode 100644 apps/backend/app/Http/Requests/Image/UpdateImageRequest.php create mode 100644 apps/backend/app/Http/Requests/Permission/StorePermissionRequest.php create mode 100644 apps/backend/app/Http/Requests/Permission/UpdatePermissionRequest.php create mode 100644 apps/backend/app/Http/Requests/Project/StoreProjectRequest.php create mode 100644 apps/backend/app/Http/Requests/Project/UpdateProjectRequest.php create mode 100644 apps/backend/app/Http/Requests/Role/StoreRoleRequest.php create mode 100644 apps/backend/app/Http/Requests/Role/UpdateRoleRequest.php create mode 100644 apps/backend/app/Http/Requests/Section/StoreSectionRequest.php create mode 100644 apps/backend/app/Http/Requests/Section/UpdateSectionRequest.php create mode 100644 apps/backend/app/Http/Requests/SubCriterion/StoreSubCriterionRequest.php create mode 100644 apps/backend/app/Http/Requests/SubCriterion/UpdateSubCriterionRequest.php create mode 100644 apps/backend/app/Http/Requests/Table/StoreTableRequest.php create mode 100644 apps/backend/app/Http/Requests/Table/UpdateTableRequest.php create mode 100644 apps/backend/app/Http/Requests/TextBlock/StoreTextBlockRequest.php create mode 100644 apps/backend/app/Http/Requests/TextBlock/UpdateTextBlockRequest.php create mode 100644 apps/backend/app/Http/Requests/TimeBlock/StoreTimeBlockRequest.php create mode 100644 apps/backend/app/Http/Requests/TimeBlock/UpdateTimeBlockRequest.php create mode 100644 apps/backend/app/Http/Requests/User/StoreUserRequest.php create mode 100644 apps/backend/app/Http/Requests/User/UpdateUserRequest.php create mode 100644 apps/backend/app/Http/Requests/UserMeta/StoreUserMetaRequest.php create mode 100644 apps/backend/app/Http/Requests/UserMeta/UpdateUserMetaRequest.php create mode 100644 apps/backend/app/Http/Requests/UserSubCriterion/StoreUserSubCriterionRequest.php create mode 100644 apps/backend/app/Http/Requests/UserSubCriterion/UpdateUserSubCriterionRequest.php create mode 100644 apps/backend/app/Http/Requests/Year/StoreYearRequest.php create mode 100644 apps/backend/app/Http/Requests/Year/UpdateYearRequest.php diff --git a/apps/backend/app/Http/Controllers/AiRatingController.php b/apps/backend/app/Http/Controllers/AiRatingController.php new file mode 100644 index 0000000..9ac20fd --- /dev/null +++ b/apps/backend/app/Http/Controllers/AiRatingController.php @@ -0,0 +1,39 @@ +validated()); + return response()->json($item, 201); + } + + public function update(UpdateAiRatingRequest $request, string $id) + { + $item = AiRating::findOrFail($id); + $item->update($request->validated()); + return response()->json($item, 200); + } + + public function delete(string $id) + { + AiRating::findOrFail($id)->delete(); + return response()->json(null, 204); + } +} diff --git a/apps/backend/app/Http/Controllers/AuthController.php b/apps/backend/app/Http/Controllers/AuthController.php index 309b098..ebb454a 100644 --- a/apps/backend/app/Http/Controllers/AuthController.php +++ b/apps/backend/app/Http/Controllers/AuthController.php @@ -11,15 +11,15 @@ class AuthController extends Controller { - public function getPermissions() + private function getRole() { $user = Auth::user(); if (!$user) { return response()->json(['error' => 'User not found'], 404); } - $permissions = $user->getPermissionNames(); - return response()->json(['permissions' => $permissions]); + $role = $user->getRoleNames(); + return response()->json(['role' => $role]); } public function register(Request $request) { @@ -88,7 +88,12 @@ public function getUser() if (!$user) { return response()->json(['error' => 'User not found'], 404); } - return response()->json($user); + $role = $user->getRoleNames(); + + return response()->json([ + 'user' => $user, + 'role' => $role + ]); } catch (JWTException $e) { return response()->json(['error' => 'Failed to fetch user profile'], 500); } diff --git a/apps/backend/app/Http/Controllers/ChapterController.php b/apps/backend/app/Http/Controllers/ChapterController.php new file mode 100644 index 0000000..e00747b --- /dev/null +++ b/apps/backend/app/Http/Controllers/ChapterController.php @@ -0,0 +1,39 @@ +validated()); + return response()->json($item, 201); + } + + public function update(UpdateChapterRequest $request, string $id) + { + $item = Chapter::findOrFail($id); + $item->update($request->validated()); + return response()->json($item, 200); + } + + public function delete(string $id) + { + Chapter::findOrFail($id)->delete(); + return response()->json(null, 204); + } +} diff --git a/apps/backend/app/Http/Controllers/CriterionController.php b/apps/backend/app/Http/Controllers/CriterionController.php new file mode 100644 index 0000000..ec56f77 --- /dev/null +++ b/apps/backend/app/Http/Controllers/CriterionController.php @@ -0,0 +1,39 @@ +validated()); + return response()->json($item, 201); + } + + public function update(UpdateCriterionRequest $request, string $id) + { + $item = Criterion::findOrFail($id); + $item->update($request->validated()); + return response()->json($item, 200); + } + + public function delete(string $id) + { + Criterion::findOrFail($id)->delete(); + return response()->json(null, 204); + } +} diff --git a/apps/backend/app/Http/Controllers/GlossariesController.php b/apps/backend/app/Http/Controllers/GlossariesController.php new file mode 100644 index 0000000..0db3020 --- /dev/null +++ b/apps/backend/app/Http/Controllers/GlossariesController.php @@ -0,0 +1,2 @@ +validated()); + return response()->json($item, 201); + } + + public function update(UpdateGlossaryRequest $request, string $id) + { + $item = Glossary::findOrFail($id); + $item->update($request->validated()); + return response()->json($item, 200); + } + + public function delete(string $id) + { + Glossary::findOrFail($id)->delete(); + return response()->json(null, 204); + } +} diff --git a/apps/backend/app/Http/Controllers/ImageController.php b/apps/backend/app/Http/Controllers/ImageController.php new file mode 100644 index 0000000..5e801b5 --- /dev/null +++ b/apps/backend/app/Http/Controllers/ImageController.php @@ -0,0 +1,39 @@ +validated()); + return response()->json($item, 201); + } + + public function update(UpdateImageRequest $request, string $id) + { + $item = Image::findOrFail($id); + $item->update($request->validated()); + return response()->json($item, 200); + } + + public function delete(string $id) + { + Image::findOrFail($id)->delete(); + return response()->json(null, 204); + } +} diff --git a/apps/backend/app/Http/Controllers/PermissionController.php b/apps/backend/app/Http/Controllers/PermissionController.php new file mode 100644 index 0000000..3e84a84 --- /dev/null +++ b/apps/backend/app/Http/Controllers/PermissionController.php @@ -0,0 +1,39 @@ +validated()); + return response()->json($item, 201); + } + + public function update(UpdatePermissionRequest $request, string $id) + { + $item = Permission::findOrFail($id); + $item->update($request->validated()); + return response()->json($item, 200); + } + + public function delete(string $id) + { + Permission::findOrFail($id)->delete(); + return response()->json(null, 204); + } +} diff --git a/apps/backend/app/Http/Controllers/ProjectController.php b/apps/backend/app/Http/Controllers/ProjectController.php index 823091e..b674cb7 100644 --- a/apps/backend/app/Http/Controllers/ProjectController.php +++ b/apps/backend/app/Http/Controllers/ProjectController.php @@ -5,9 +5,40 @@ use Illuminate\Http\Request; use App\Models\Project; use App\Models\Chapter; +use App\Http\Requests\Project\StoreProjectRequest; +use App\Http\Requests\Project\UpdateProjectRequest; class ProjectController extends Controller { + public function index() + { + return Project::all(); + } + + public function show(string $id) + { + return Project::findOrFail($id); + } + + public function store(StoreProjectRequest $request) + { + $project = Project::create($request->validated()); + return response()->json($project, 201); + } + + public function update(UpdateProjectRequest $request, string $id) + { + $project = Project::findOrFail($id); + $project->update($request->validated()); + return response()->json($project, 200); + } + + public function delete(string $id) + { + Project::findOrFail($id)->delete(); + return response()->json(null, 204); + } + public function createProject(Request $request) { $validatedData = $request->validate([ diff --git a/apps/backend/app/Http/Controllers/ProjectCrudController.php b/apps/backend/app/Http/Controllers/ProjectCrudController.php new file mode 100644 index 0000000..74bda9c --- /dev/null +++ b/apps/backend/app/Http/Controllers/ProjectCrudController.php @@ -0,0 +1,39 @@ +all()); + return response()->json($item, 201); + } + + public function update(UpdateProjectRequest $request, string $id) + { + $item = Project::findOrFail($id); + $item->update($request->all()); + return response()->json($item, 200); + } + + public function delete(string $id) + { + Project::findOrFail($id)->delete(); + return response()->json(null, 204); + } +} diff --git a/apps/backend/app/Http/Controllers/ProjectSController.php b/apps/backend/app/Http/Controllers/ProjectSController.php new file mode 100644 index 0000000..0eb3504 --- /dev/null +++ b/apps/backend/app/Http/Controllers/ProjectSController.php @@ -0,0 +1,2 @@ +validated()); + return response()->json($item, 201); + } + + public function update(UpdateRoleRequest $request, string $id) + { + $item = Role::findOrFail($id); + $item->update($request->validated()); + return response()->json($item, 200); + } + + public function delete(string $id) + { + Role::findOrFail($id)->delete(); + return response()->json(null, 204); + } +} diff --git a/apps/backend/app/Http/Controllers/SectionController.php b/apps/backend/app/Http/Controllers/SectionController.php new file mode 100644 index 0000000..54ff563 --- /dev/null +++ b/apps/backend/app/Http/Controllers/SectionController.php @@ -0,0 +1,39 @@ +validated()); + return response()->json($item, 201); + } + + public function update(UpdateSectionRequest $request, string $id) + { + $item = Section::findOrFail($id); + $item->update($request->validated()); + return response()->json($item, 200); + } + + public function delete(string $id) + { + Section::findOrFail($id)->delete(); + return response()->json(null, 204); + } +} diff --git a/apps/backend/app/Http/Controllers/SubCriterionController.php b/apps/backend/app/Http/Controllers/SubCriterionController.php new file mode 100644 index 0000000..017c65c --- /dev/null +++ b/apps/backend/app/Http/Controllers/SubCriterionController.php @@ -0,0 +1,39 @@ +validated()); + return response()->json($item, 201); + } + + public function update(UpdateSubCriterionRequest $request, string $id) + { + $item = SubCriterion::findOrFail($id); + $item->update($request->validated()); + return response()->json($item, 200); + } + + public function delete(string $id) + { + SubCriterion::findOrFail($id)->delete(); + return response()->json(null, 204); + } +} diff --git a/apps/backend/app/Http/Controllers/TableController.php b/apps/backend/app/Http/Controllers/TableController.php new file mode 100644 index 0000000..b4edb89 --- /dev/null +++ b/apps/backend/app/Http/Controllers/TableController.php @@ -0,0 +1,39 @@ +validated()); + return response()->json($item, 201); + } + + public function update(UpdateTableRequest $request, string $id) + { + $item = Table::findOrFail($id); + $item->update($request->validated()); + return response()->json($item, 200); + } + + public function delete(string $id) + { + Table::findOrFail($id)->delete(); + return response()->json(null, 204); + } +} diff --git a/apps/backend/app/Http/Controllers/TextBlockController.php b/apps/backend/app/Http/Controllers/TextBlockController.php new file mode 100644 index 0000000..8320227 --- /dev/null +++ b/apps/backend/app/Http/Controllers/TextBlockController.php @@ -0,0 +1,39 @@ +validated()); + return response()->json($item, 201); + } + + public function update(UpdateTextBlockRequest $request, string $id) + { + $item = TextBlock::findOrFail($id); + $item->update($request->validated()); + return response()->json($item, 200); + } + + public function delete(string $id) + { + TextBlock::findOrFail($id)->delete(); + return response()->json(null, 204); + } +} diff --git a/apps/backend/app/Http/Controllers/TimeBlockController.php b/apps/backend/app/Http/Controllers/TimeBlockController.php new file mode 100644 index 0000000..b27a217 --- /dev/null +++ b/apps/backend/app/Http/Controllers/TimeBlockController.php @@ -0,0 +1,39 @@ +validated()); + return response()->json($item, 201); + } + + public function update(UpdateTimeBlockRequest $request, string $id) + { + $item = TimeBlock::findOrFail($id); + $item->update($request->validated()); + return response()->json($item, 200); + } + + public function delete(string $id) + { + TimeBlock::findOrFail($id)->delete(); + return response()->json(null, 204); + } +} diff --git a/apps/backend/app/Http/Controllers/UserController.php b/apps/backend/app/Http/Controllers/UserController.php new file mode 100644 index 0000000..71e51d9 --- /dev/null +++ b/apps/backend/app/Http/Controllers/UserController.php @@ -0,0 +1,39 @@ +all()); + return response()->json($item, 201); + } + + public function update(UpdateUserRequest $request, string $id) + { + $item = User::findOrFail($id); + $item->update($request->all()); + return response()->json($item, 200); + } + + public function delete(string $id) + { + User::findOrFail($id)->delete(); + return response()->json(null, 204); + } +} diff --git a/apps/backend/app/Http/Controllers/UserMetaController.php b/apps/backend/app/Http/Controllers/UserMetaController.php new file mode 100644 index 0000000..81b90f7 --- /dev/null +++ b/apps/backend/app/Http/Controllers/UserMetaController.php @@ -0,0 +1,39 @@ +all()); + return response()->json($item, 201); + } + + public function update(UpdateUserMetaRequest $request, string $id) + { + $item = UserMeta::findOrFail($id); + $item->update($request->all()); + return response()->json($item, 200); + } + + public function delete(string $id) + { + UserMeta::findOrFail($id)->delete(); + return response()->json(null, 204); + } +} diff --git a/apps/backend/app/Http/Controllers/UserSubCriterionController.php b/apps/backend/app/Http/Controllers/UserSubCriterionController.php new file mode 100644 index 0000000..91721a9 --- /dev/null +++ b/apps/backend/app/Http/Controllers/UserSubCriterionController.php @@ -0,0 +1,39 @@ +all()); + return response()->json($item, 201); + } + + public function update(UpdateUserSubCriterionRequest $request, string $id) + { + $item = UserSubCriterion::findOrFail($id); + $item->update($request->all()); + return response()->json($item, 200); + } + + public function delete(string $id) + { + UserSubCriterion::findOrFail($id)->delete(); + return response()->json(null, 204); + } +} diff --git a/apps/backend/app/Http/Controllers/YearController.php b/apps/backend/app/Http/Controllers/YearController.php index de2e460..c23c2f6 100644 --- a/apps/backend/app/Http/Controllers/YearController.php +++ b/apps/backend/app/Http/Controllers/YearController.php @@ -3,7 +3,8 @@ namespace App\Http\Controllers; use App\Models\Year; -use Illuminate\Http\Request; +use App\Http\Requests\Year\StoreYearRequest; +use App\Http\Requests\Year\UpdateYearRequest; class YearController extends Controller { @@ -17,16 +18,16 @@ public function show($id) return Year::findOrFail($id); } - public function store(Request $request) + public function store(StoreYearRequest $request) { - $year = Year::create($request->all()); + $year = Year::create($request->validated()); return response()->json($year, 201); } - public function update(Request $request, $id) + public function update(UpdateYearRequest $request, $id) { $year = Year::findOrFail($id); - $year->update($request->all()); + $year->update($request->validated()); return response()->json($year, 200); } diff --git a/apps/backend/app/Http/Requests/AiRating/StoreAiRatingRequest.php b/apps/backend/app/Http/Requests/AiRating/StoreAiRatingRequest.php new file mode 100644 index 0000000..78f50d8 --- /dev/null +++ b/apps/backend/app/Http/Requests/AiRating/StoreAiRatingRequest.php @@ -0,0 +1,16 @@ + 'required|exists:sections,id', + 'rating' => 'required|integer|min:1|max:6', + 'rating_description' => 'nullable|string', + 'rating_checksum' => 'nullable|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/AiRating/UpdateAiRatingRequest.php b/apps/backend/app/Http/Requests/AiRating/UpdateAiRatingRequest.php new file mode 100644 index 0000000..a8e435b --- /dev/null +++ b/apps/backend/app/Http/Requests/AiRating/UpdateAiRatingRequest.php @@ -0,0 +1,16 @@ + 'sometimes|exists:sections,id', + 'rating' => 'sometimes|integer|min:1|max:6', + 'rating_description' => 'nullable|string', + 'rating_checksum' => 'nullable|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/Chapter/StoreChapterRequest.php b/apps/backend/app/Http/Requests/Chapter/StoreChapterRequest.php new file mode 100644 index 0000000..baedba2 --- /dev/null +++ b/apps/backend/app/Http/Requests/Chapter/StoreChapterRequest.php @@ -0,0 +1,16 @@ + 'required|exists:projects,id', + 'type' => 'required|string', + 'title' => 'required|string|max:255', + 'subtitle' => 'nullable|string|max:255', + ]; } +} diff --git a/apps/backend/app/Http/Requests/Chapter/UpdateChapterRequest.php b/apps/backend/app/Http/Requests/Chapter/UpdateChapterRequest.php new file mode 100644 index 0000000..6dc7e1f --- /dev/null +++ b/apps/backend/app/Http/Requests/Chapter/UpdateChapterRequest.php @@ -0,0 +1,16 @@ + 'sometimes|exists:projects,id', + 'type' => 'sometimes|string', + 'title' => 'sometimes|string|max:255', + 'subtitle' => 'nullable|string|max:255', + ]; } +} diff --git a/apps/backend/app/Http/Requests/Criterion/StoreCriterionRequest.php b/apps/backend/app/Http/Requests/Criterion/StoreCriterionRequest.php new file mode 100644 index 0000000..8161884 --- /dev/null +++ b/apps/backend/app/Http/Requests/Criterion/StoreCriterionRequest.php @@ -0,0 +1,16 @@ + 'required|exists:years,id', + 'title' => 'required|string', + 'description' => 'nullable|string', + 'special_for_project_id' => 'nullable|exists:projects,id', + ]; } +} diff --git a/apps/backend/app/Http/Requests/Criterion/UpdateCriterionRequest.php b/apps/backend/app/Http/Requests/Criterion/UpdateCriterionRequest.php new file mode 100644 index 0000000..2268564 --- /dev/null +++ b/apps/backend/app/Http/Requests/Criterion/UpdateCriterionRequest.php @@ -0,0 +1,16 @@ + 'sometimes|exists:years,id', + 'title' => 'sometimes|string', + 'description' => 'nullable|string', + 'special_for_project_id' => 'nullable|exists:projects,id', + ]; } +} diff --git a/apps/backend/app/Http/Requests/Glossary/StoreGlossaryRequest.php b/apps/backend/app/Http/Requests/Glossary/StoreGlossaryRequest.php new file mode 100644 index 0000000..d64c249 --- /dev/null +++ b/apps/backend/app/Http/Requests/Glossary/StoreGlossaryRequest.php @@ -0,0 +1,15 @@ + 'required|exists:projects,id', + 'term' => 'required|string', + 'definition' => 'required|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/Glossary/UpdateGlossaryRequest.php b/apps/backend/app/Http/Requests/Glossary/UpdateGlossaryRequest.php new file mode 100644 index 0000000..18f31ff --- /dev/null +++ b/apps/backend/app/Http/Requests/Glossary/UpdateGlossaryRequest.php @@ -0,0 +1,15 @@ + 'sometimes|exists:projects,id', + 'term' => 'sometimes|string', + 'definition' => 'sometimes|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/Image/StoreImageRequest.php b/apps/backend/app/Http/Requests/Image/StoreImageRequest.php new file mode 100644 index 0000000..70b2040 --- /dev/null +++ b/apps/backend/app/Http/Requests/Image/StoreImageRequest.php @@ -0,0 +1,17 @@ + 'required|exists:sections,id', + 'position' => 'required|integer', + 'image_data' => 'required|string', + 'description' => 'nullable|string', + 'source' => 'nullable|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/Image/UpdateImageRequest.php b/apps/backend/app/Http/Requests/Image/UpdateImageRequest.php new file mode 100644 index 0000000..42ba2ba --- /dev/null +++ b/apps/backend/app/Http/Requests/Image/UpdateImageRequest.php @@ -0,0 +1,17 @@ + 'sometimes|exists:sections,id', + 'position' => 'sometimes|integer', + 'image_data' => 'sometimes|string', + 'description' => 'nullable|string', + 'source' => 'nullable|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/Permission/StorePermissionRequest.php b/apps/backend/app/Http/Requests/Permission/StorePermissionRequest.php new file mode 100644 index 0000000..6d2e0c0 --- /dev/null +++ b/apps/backend/app/Http/Requests/Permission/StorePermissionRequest.php @@ -0,0 +1,14 @@ + 'required|string|unique:permissions,name', + 'guard_name' => 'nullable|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/Permission/UpdatePermissionRequest.php b/apps/backend/app/Http/Requests/Permission/UpdatePermissionRequest.php new file mode 100644 index 0000000..bb54a07 --- /dev/null +++ b/apps/backend/app/Http/Requests/Permission/UpdatePermissionRequest.php @@ -0,0 +1,14 @@ + 'sometimes|string|unique:permissions,name,' . $this->route('id'), + 'guard_name' => 'nullable|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/Project/StoreProjectRequest.php b/apps/backend/app/Http/Requests/Project/StoreProjectRequest.php new file mode 100644 index 0000000..bdb7b4a --- /dev/null +++ b/apps/backend/app/Http/Requests/Project/StoreProjectRequest.php @@ -0,0 +1,25 @@ + 'required|exists:years,id', + 'owner_id' => 'required|exists:users,id', + 'name' => 'required|string|max:255', + 'start_date' => 'required|date', + 'end_date' => 'required|date|after_or_equal:start_date', + 'description' => 'nullable|string', + ]; + } +} diff --git a/apps/backend/app/Http/Requests/Project/UpdateProjectRequest.php b/apps/backend/app/Http/Requests/Project/UpdateProjectRequest.php new file mode 100644 index 0000000..6a2ccb5 --- /dev/null +++ b/apps/backend/app/Http/Requests/Project/UpdateProjectRequest.php @@ -0,0 +1,25 @@ + 'sometimes|exists:years,id', + 'owner_id' => 'sometimes|exists:users,id', + 'name' => 'sometimes|string|max:255', + 'start_date' => 'sometimes|date', + 'end_date' => 'sometimes|date|after_or_equal:start_date', + 'description' => 'nullable|string', + ]; + } +} diff --git a/apps/backend/app/Http/Requests/Role/StoreRoleRequest.php b/apps/backend/app/Http/Requests/Role/StoreRoleRequest.php new file mode 100644 index 0000000..144e627 --- /dev/null +++ b/apps/backend/app/Http/Requests/Role/StoreRoleRequest.php @@ -0,0 +1,14 @@ + 'required|string|unique:roles,name', + 'guard_name' => 'nullable|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/Role/UpdateRoleRequest.php b/apps/backend/app/Http/Requests/Role/UpdateRoleRequest.php new file mode 100644 index 0000000..b15d2c5 --- /dev/null +++ b/apps/backend/app/Http/Requests/Role/UpdateRoleRequest.php @@ -0,0 +1,14 @@ + 'sometimes|string|unique:roles,name,' . $this->route('id'), + 'guard_name' => 'nullable|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/Section/StoreSectionRequest.php b/apps/backend/app/Http/Requests/Section/StoreSectionRequest.php new file mode 100644 index 0000000..d9e72db --- /dev/null +++ b/apps/backend/app/Http/Requests/Section/StoreSectionRequest.php @@ -0,0 +1,18 @@ + 'required|exists:chapters,id', + 'parent_id' => 'nullable|exists:sections,id', + 'position' => 'required|integer', + 'title' => 'required|string', + 'subtitle' => 'nullable|string', + 'rating_checksum' => 'nullable|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/Section/UpdateSectionRequest.php b/apps/backend/app/Http/Requests/Section/UpdateSectionRequest.php new file mode 100644 index 0000000..a2f9e39 --- /dev/null +++ b/apps/backend/app/Http/Requests/Section/UpdateSectionRequest.php @@ -0,0 +1,18 @@ + 'sometimes|exists:chapters,id', + 'parent_id' => 'nullable|exists:sections,id', + 'position' => 'sometimes|integer', + 'title' => 'sometimes|string', + 'subtitle' => 'nullable|string', + 'rating_checksum' => 'nullable|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/SubCriterion/StoreSubCriterionRequest.php b/apps/backend/app/Http/Requests/SubCriterion/StoreSubCriterionRequest.php new file mode 100644 index 0000000..ef6d756 --- /dev/null +++ b/apps/backend/app/Http/Requests/SubCriterion/StoreSubCriterionRequest.php @@ -0,0 +1,14 @@ + 'required|exists:criteria,id', + 'description' => 'required|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/SubCriterion/UpdateSubCriterionRequest.php b/apps/backend/app/Http/Requests/SubCriterion/UpdateSubCriterionRequest.php new file mode 100644 index 0000000..4fe5f57 --- /dev/null +++ b/apps/backend/app/Http/Requests/SubCriterion/UpdateSubCriterionRequest.php @@ -0,0 +1,14 @@ + 'sometimes|exists:criteria,id', + 'description' => 'sometimes|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/Table/StoreTableRequest.php b/apps/backend/app/Http/Requests/Table/StoreTableRequest.php new file mode 100644 index 0000000..46242e4 --- /dev/null +++ b/apps/backend/app/Http/Requests/Table/StoreTableRequest.php @@ -0,0 +1,17 @@ + 'required|exists:sections,id', + 'position' => 'required|integer', + 'heading' => 'nullable|string', + 'markdown_table' => 'required|string', + 'source' => 'nullable|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/Table/UpdateTableRequest.php b/apps/backend/app/Http/Requests/Table/UpdateTableRequest.php new file mode 100644 index 0000000..a040450 --- /dev/null +++ b/apps/backend/app/Http/Requests/Table/UpdateTableRequest.php @@ -0,0 +1,17 @@ + 'sometimes|exists:sections,id', + 'position' => 'sometimes|integer', + 'heading' => 'nullable|string', + 'markdown_table' => 'sometimes|string', + 'source' => 'nullable|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/TextBlock/StoreTextBlockRequest.php b/apps/backend/app/Http/Requests/TextBlock/StoreTextBlockRequest.php new file mode 100644 index 0000000..7f070ee --- /dev/null +++ b/apps/backend/app/Http/Requests/TextBlock/StoreTextBlockRequest.php @@ -0,0 +1,17 @@ + 'required|exists:sections,id', + 'position' => 'required|integer', + 'heading' => 'nullable|string', + 'text' => 'required|string', + 'source' => 'nullable|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/TextBlock/UpdateTextBlockRequest.php b/apps/backend/app/Http/Requests/TextBlock/UpdateTextBlockRequest.php new file mode 100644 index 0000000..9a02d4f --- /dev/null +++ b/apps/backend/app/Http/Requests/TextBlock/UpdateTextBlockRequest.php @@ -0,0 +1,17 @@ + 'sometimes|exists:sections,id', + 'position' => 'sometimes|integer', + 'heading' => 'nullable|string', + 'text' => 'sometimes|string', + 'source' => 'nullable|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/TimeBlock/StoreTimeBlockRequest.php b/apps/backend/app/Http/Requests/TimeBlock/StoreTimeBlockRequest.php new file mode 100644 index 0000000..55c1aa0 --- /dev/null +++ b/apps/backend/app/Http/Requests/TimeBlock/StoreTimeBlockRequest.php @@ -0,0 +1,17 @@ + 'required|exists:projects,id', + 'description' => 'required|string', + 'is_chore' => 'required|boolean', + 'start_time' => 'required|date', + 'end_time' => 'required|date|after_or_equal:start_time', + ]; } +} diff --git a/apps/backend/app/Http/Requests/TimeBlock/UpdateTimeBlockRequest.php b/apps/backend/app/Http/Requests/TimeBlock/UpdateTimeBlockRequest.php new file mode 100644 index 0000000..41aff0e --- /dev/null +++ b/apps/backend/app/Http/Requests/TimeBlock/UpdateTimeBlockRequest.php @@ -0,0 +1,17 @@ + 'sometimes|exists:projects,id', + 'description' => 'sometimes|string', + 'is_chore' => 'sometimes|boolean', + 'start_time' => 'sometimes|date', + 'end_time' => 'sometimes|date|after_or_equal:start_time', + ]; } +} diff --git a/apps/backend/app/Http/Requests/User/StoreUserRequest.php b/apps/backend/app/Http/Requests/User/StoreUserRequest.php new file mode 100644 index 0000000..7a7bbcb --- /dev/null +++ b/apps/backend/app/Http/Requests/User/StoreUserRequest.php @@ -0,0 +1,16 @@ + 'required|string|max:255', + 'last_name' => 'required|string|max:255', + 'email' => 'required|email|unique:users,email', + 'password' => 'required|string|min:8', + ]; } +} diff --git a/apps/backend/app/Http/Requests/User/UpdateUserRequest.php b/apps/backend/app/Http/Requests/User/UpdateUserRequest.php new file mode 100644 index 0000000..3eab7d1 --- /dev/null +++ b/apps/backend/app/Http/Requests/User/UpdateUserRequest.php @@ -0,0 +1,16 @@ + 'sometimes|string|max:255', + 'last_name' => 'sometimes|string|max:255', + 'email' => 'sometimes|email|unique:users,email,' . $this->route('id'), + 'password' => 'sometimes|string|min:8', + ]; } +} diff --git a/apps/backend/app/Http/Requests/UserMeta/StoreUserMetaRequest.php b/apps/backend/app/Http/Requests/UserMeta/StoreUserMetaRequest.php new file mode 100644 index 0000000..09f6fcb --- /dev/null +++ b/apps/backend/app/Http/Requests/UserMeta/StoreUserMetaRequest.php @@ -0,0 +1,15 @@ + 'required|exists:users,id', + 'meta_key' => 'required|string', + 'meta_value' => 'required|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/UserMeta/UpdateUserMetaRequest.php b/apps/backend/app/Http/Requests/UserMeta/UpdateUserMetaRequest.php new file mode 100644 index 0000000..5d44066 --- /dev/null +++ b/apps/backend/app/Http/Requests/UserMeta/UpdateUserMetaRequest.php @@ -0,0 +1,15 @@ + 'sometimes|exists:users,id', + 'meta_key' => 'sometimes|string', + 'meta_value' => 'sometimes|string', + ]; } +} diff --git a/apps/backend/app/Http/Requests/UserSubCriterion/StoreUserSubCriterionRequest.php b/apps/backend/app/Http/Requests/UserSubCriterion/StoreUserSubCriterionRequest.php new file mode 100644 index 0000000..e4f5ce6 --- /dev/null +++ b/apps/backend/app/Http/Requests/UserSubCriterion/StoreUserSubCriterionRequest.php @@ -0,0 +1,15 @@ + 'required|exists:sub_criteria,id', + 'user_id' => 'required|exists:users,id', + 'is_fulfilled' => 'required|boolean', + ]; } +} diff --git a/apps/backend/app/Http/Requests/UserSubCriterion/UpdateUserSubCriterionRequest.php b/apps/backend/app/Http/Requests/UserSubCriterion/UpdateUserSubCriterionRequest.php new file mode 100644 index 0000000..4e31808 --- /dev/null +++ b/apps/backend/app/Http/Requests/UserSubCriterion/UpdateUserSubCriterionRequest.php @@ -0,0 +1,15 @@ + 'sometimes|exists:sub_criteria,id', + 'user_id' => 'sometimes|exists:users,id', + 'is_fulfilled' => 'sometimes|boolean', + ]; } +} diff --git a/apps/backend/app/Http/Requests/Year/StoreYearRequest.php b/apps/backend/app/Http/Requests/Year/StoreYearRequest.php new file mode 100644 index 0000000..ba1dbba --- /dev/null +++ b/apps/backend/app/Http/Requests/Year/StoreYearRequest.php @@ -0,0 +1,21 @@ + 'required|integer|min:1900|max:3000', + 'is_active' => 'required|boolean', + ]; + } +} diff --git a/apps/backend/app/Http/Requests/Year/UpdateYearRequest.php b/apps/backend/app/Http/Requests/Year/UpdateYearRequest.php new file mode 100644 index 0000000..fc85433 --- /dev/null +++ b/apps/backend/app/Http/Requests/Year/UpdateYearRequest.php @@ -0,0 +1,21 @@ + 'sometimes|integer|min:1900|max:3000', + 'is_active' => 'sometimes|boolean', + ]; + } +} diff --git a/apps/backend/app/Models/User.php b/apps/backend/app/Models/User.php index 25de6d4..02720c3 100644 --- a/apps/backend/app/Models/User.php +++ b/apps/backend/app/Models/User.php @@ -6,6 +6,7 @@ use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Illuminate\Support\Str; +use Spatie\Permission\Traits\HasPermissions; use Spatie\Permission\Traits\HasRoles; use Tymon\JWTAuth\Contracts\JWTSubject; @@ -13,7 +14,7 @@ class User extends Authenticatable implements JWTSubject { /** @use HasFactory<\Database\Factories\UserFactory> */ - use HasFactory, Notifiable, HasRoles; + use HasFactory, Notifiable, HasRoles, HasPermissions; protected $keyType = 'string'; public $incrementing = false; diff --git a/apps/backend/database/seeders/DatabaseSeeder.php b/apps/backend/database/seeders/DatabaseSeeder.php index b9acee6..556f89b 100644 --- a/apps/backend/database/seeders/DatabaseSeeder.php +++ b/apps/backend/database/seeders/DatabaseSeeder.php @@ -3,6 +3,7 @@ namespace Database\Seeders; use Illuminate\Database\Seeder; + use App\Models\{ Year, User, @@ -32,6 +33,46 @@ public function run(): void $years = Year::factory()->count(rand(5, 10))->create(); $users = User::factory()->count(rand(5, 10))->create(); + $admin = User::factory()->create([ + 'first_name' => 'Herr', + 'last_name' => 'Admin', + 'email' => 'admin@sesh.com', + 'password' => bcrypt('password'), + ]); + + $apprentice = User::factory()->create([ + 'first_name' => 'Herr', + 'last_name' => 'Lehrling', + 'email' => 'apprentice@sesh.com', + 'password' => bcrypt('password'), + ]); + + $supervisor = User::factory()->create([ + 'first_name' => 'Herr', + 'last_name' => 'Berufsausbilder', + 'email' => 'supervisor@sesh.com', + 'password' => bcrypt('password'), + ]); + + $mentor = User::factory()->create([ + 'first_name' => 'Herr', + 'last_name' => 'Praxisbildner', + 'email' => 'mentor@sesh.com', + 'password' => bcrypt('password'), + ]); + + $adminUser = User::where('email', 'admin@sesh.com')->first(); + $adminUser->assignRole('admin'); + + $apprenticeUser = User::where('email', 'apprentice@sesh.com')->first(); + $apprenticeUser->assignRole('apprentice'); + + $supervisorUser = User::where('email', 'supervisor@sesh.com')->first(); + $supervisorUser->assignRole('supervisor'); + + $mentorUser = User::where('email', 'mentor@sesh.com')->first(); + $mentorUser->assignRole('mentor'); + // Projects linked to existing Years and Users $projects = Project::factory() ->count(rand(5, 10)) diff --git a/apps/backend/routes/api.php b/apps/backend/routes/api.php index e9b4268..cf50145 100644 --- a/apps/backend/routes/api.php +++ b/apps/backend/routes/api.php @@ -5,28 +5,70 @@ use App\Http\Controllers\AuthController; use App\Http\Controllers\ProjectController; -Route::post('/register', [AuthController::class, 'register']); -Route::post('/login', [AuthController::class, 'login']); +$tables = [ + 'ai_ratings', + 'cache', + 'cache_locks', + 'chapters', + 'criteria', + 'failed_jobs', + 'glossaries', + 'images', + 'job_batches', + 'jobs', + 'migrations', + 'model_has_permissions', + 'model_has_roles', + 'password_reset_tokens', + 'permissions', + 'personal_access_tokens', + 'projects', + 'role_has_permissions', + 'roles', + 'sections', + 'sessions', + 'sub_criteria', + 'tables', + 'text_blocks', + 'time_blocks', + 'user_metas', + 'user_sub_criteria', + 'users', + 'years', +]; -Route::middleware('jwt')->group(function () { - Route::get('/user', [AuthController::class, 'getUser']); - Route::get('/permissions', [AuthController::class, 'getPermissions']); - Route::put('/user', [AuthController::class, 'updateUser']); - Route::post('/logout', [AuthController::class, 'logout']); -}); +// Auth +Route::post('auth/register', [AuthController::class, 'register']); +Route::post('auth/login', [AuthController::class, 'login']); Route::middleware('jwt') - ->prefix('project') + ->prefix('auth') ->group(function () { - Route::post('/create', [ProjectController::class, 'createProject']); + Route::get('/', [AuthController::class, 'getUser']); + Route::put('/user', [AuthController::class, 'updateUser']); + Route::post('/logout', [AuthController::class, 'logout']); }); +// CRUD +foreach ($tables as $table) { + $controller = str_replace(' ', '', ucwords(str_replace('_', ' ', \Illuminate\Support\Str::singular($table)))) . 'Controller'; + + Route::middleware('jwt') + ->prefix("crud/{$table}") + ->group(function () use ($controller) { + Route::get('/', ["App\\Http\\Controllers\\$controller", 'index']); + Route::get('/{id}', ["App\\Http\\Controllers\\$controller", 'show']); + Route::post('/', ["App\\Http\\Controllers\\$controller", 'store']); + Route::put('/{id}', ["App\\Http\\Controllers\\$controller", 'update']); + Route::delete('/{id}', ["App\\Http\\Controllers\\$controller", 'delete']); + }); +} + + Route::middleware('jwt') - ->prefix('year') + ->prefix('project') ->group(function () { - Route::get('/', [App\Http\Controllers\YearController::class, 'index']); - Route::get('/{id}', [App\Http\Controllers\YearController::class, 'show']); - Route::post('/', [App\Http\Controllers\YearController::class, 'store']); - Route::put('/{id}', [App\Http\Controllers\YearController::class, 'update']); - Route::delete('/{id}', [App\Http\Controllers\YearController::class, 'delete']); + Route::post('/create', [ProjectController::class, 'createProject']); }); + + From 278ce348092d3e9f6bc72db8ce0d655868f9da7f Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 09:00:07 +0200 Subject: [PATCH 16/22] refactor: remove unused files --- apps/backend/app/Http/Controllers/GlossariesController.php | 2 -- apps/backend/app/Http/Controllers/ProjectSController.php | 2 -- 2 files changed, 4 deletions(-) delete mode 100644 apps/backend/app/Http/Controllers/GlossariesController.php delete mode 100644 apps/backend/app/Http/Controllers/ProjectSController.php diff --git a/apps/backend/app/Http/Controllers/GlossariesController.php b/apps/backend/app/Http/Controllers/GlossariesController.php deleted file mode 100644 index 0db3020..0000000 --- a/apps/backend/app/Http/Controllers/GlossariesController.php +++ /dev/null @@ -1,2 +0,0 @@ - Date: Sat, 4 Oct 2025 09:58:48 +0200 Subject: [PATCH 17/22] fix: add position --- apps/backend/app/Http/Requests/Chapter/StoreChapterRequest.php | 1 + apps/backend/app/Http/Requests/Chapter/UpdateChapterRequest.php | 1 + .../migrations/03_2025_10_03_225025_create_chapters_table.php | 1 + 3 files changed, 3 insertions(+) diff --git a/apps/backend/app/Http/Requests/Chapter/StoreChapterRequest.php b/apps/backend/app/Http/Requests/Chapter/StoreChapterRequest.php index baedba2..dba5306 100644 --- a/apps/backend/app/Http/Requests/Chapter/StoreChapterRequest.php +++ b/apps/backend/app/Http/Requests/Chapter/StoreChapterRequest.php @@ -9,6 +9,7 @@ class StoreChapterRequest extends FormRequest public function authorize(): bool { return true; } public function rules(): array { return [ 'project_id' => 'required|exists:projects,id', + 'position' => 'required|integer', 'type' => 'required|string', 'title' => 'required|string|max:255', 'subtitle' => 'nullable|string|max:255', diff --git a/apps/backend/app/Http/Requests/Chapter/UpdateChapterRequest.php b/apps/backend/app/Http/Requests/Chapter/UpdateChapterRequest.php index 6dc7e1f..2d3d29c 100644 --- a/apps/backend/app/Http/Requests/Chapter/UpdateChapterRequest.php +++ b/apps/backend/app/Http/Requests/Chapter/UpdateChapterRequest.php @@ -9,6 +9,7 @@ class UpdateChapterRequest extends FormRequest public function authorize(): bool { return true; } public function rules(): array { return [ 'project_id' => 'sometimes|exists:projects,id', + 'position' => 'sometimes|integer', 'type' => 'sometimes|string', 'title' => 'sometimes|string|max:255', 'subtitle' => 'nullable|string|max:255', diff --git a/apps/backend/database/migrations/03_2025_10_03_225025_create_chapters_table.php b/apps/backend/database/migrations/03_2025_10_03_225025_create_chapters_table.php index c7f42fd..ad6cd2d 100644 --- a/apps/backend/database/migrations/03_2025_10_03_225025_create_chapters_table.php +++ b/apps/backend/database/migrations/03_2025_10_03_225025_create_chapters_table.php @@ -13,6 +13,7 @@ public function up(): void Schema::create('chapters', function (Blueprint $table) { $table->char('id', 36)->primary(); $table->char('project_id', 36); + $table->integer('position'); $table->string('type'); $table->string('title'); $table->text('subtitle'); From c659ca8e701d8ac04dfaf6d169e3f228277c962c Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 10:12:41 +0200 Subject: [PATCH 18/22] feat; implement foreign keys on the model --- apps/backend/app/Models/AiRating.php | 8 +++ apps/backend/app/Models/Chapter.php | 14 +++++ apps/backend/app/Models/Criterion.php | 19 ++++++ apps/backend/app/Models/Glossary.php | 8 +++ apps/backend/app/Models/Image.php | 8 +++ apps/backend/app/Models/Project.php | 61 ++++++++++++++++++++ apps/backend/app/Models/Section.php | 39 +++++++++++++ apps/backend/app/Models/SubCriterion.php | 14 +++++ apps/backend/app/Models/Table.php | 8 +++ apps/backend/app/Models/TextBlock.php | 8 +++ apps/backend/app/Models/TimeBlock.php | 8 +++ apps/backend/app/Models/User.php | 27 +++++++++ apps/backend/app/Models/UserMeta.php | 8 +++ apps/backend/app/Models/UserSubCriterion.php | 13 +++++ apps/backend/app/Models/Year.php | 19 ++++++ 15 files changed, 262 insertions(+) diff --git a/apps/backend/app/Models/AiRating.php b/apps/backend/app/Models/AiRating.php index c807633..56090e8 100644 --- a/apps/backend/app/Models/AiRating.php +++ b/apps/backend/app/Models/AiRating.php @@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Support\Str; class AiRating extends Model @@ -24,4 +25,11 @@ protected static function booted() } }); } + + // Relationships + + public function section(): BelongsTo + { + return $this->belongsTo(Section::class); + } } diff --git a/apps/backend/app/Models/Chapter.php b/apps/backend/app/Models/Chapter.php index f0704f5..2c3c685 100644 --- a/apps/backend/app/Models/Chapter.php +++ b/apps/backend/app/Models/Chapter.php @@ -4,6 +4,8 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Support\Str; class Chapter extends Model @@ -24,4 +26,16 @@ protected static function booted() } }); } + + // Relationships + + public function project(): BelongsTo + { + return $this->belongsTo(Project::class); + } + + public function sections(): HasMany + { + return $this->hasMany(Section::class); + } } diff --git a/apps/backend/app/Models/Criterion.php b/apps/backend/app/Models/Criterion.php index b2ec149..bd42546 100644 --- a/apps/backend/app/Models/Criterion.php +++ b/apps/backend/app/Models/Criterion.php @@ -4,6 +4,8 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Support\Str; class Criterion extends Model @@ -24,4 +26,21 @@ protected static function booted() } }); } + + // Relationships + + public function year(): BelongsTo + { + return $this->belongsTo(Year::class); + } + + public function specialForProject(): BelongsTo + { + return $this->belongsTo(Project::class, 'special_for_project_id'); + } + + public function subCriteria(): HasMany + { + return $this->hasMany(SubCriterion::class, 'criteria_id'); + } } diff --git a/apps/backend/app/Models/Glossary.php b/apps/backend/app/Models/Glossary.php index 1ce9e0d..1d44946 100644 --- a/apps/backend/app/Models/Glossary.php +++ b/apps/backend/app/Models/Glossary.php @@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Support\Str; class Glossary extends Model @@ -24,4 +25,11 @@ protected static function booted() } }); } + + // Relationships + + public function project(): BelongsTo + { + return $this->belongsTo(Project::class); + } } diff --git a/apps/backend/app/Models/Image.php b/apps/backend/app/Models/Image.php index d43870c..6abcce0 100644 --- a/apps/backend/app/Models/Image.php +++ b/apps/backend/app/Models/Image.php @@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Support\Str; class Image extends Model @@ -24,4 +25,11 @@ protected static function booted() } }); } + + // Relationships + + public function section(): BelongsTo + { + return $this->belongsTo(Section::class); + } } diff --git a/apps/backend/app/Models/Project.php b/apps/backend/app/Models/Project.php index b1a2f88..7d65828 100644 --- a/apps/backend/app/Models/Project.php +++ b/apps/backend/app/Models/Project.php @@ -4,6 +4,9 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\HasManyThrough; use Illuminate\Support\Str; class Project extends Model @@ -24,4 +27,62 @@ protected static function booted() } }); } + + // Relationships + + /** + * The year this project belongs to. + */ + public function year(): BelongsTo + { + return $this->belongsTo(Year::class); + } + + /** + * The user who owns this project. + */ + public function owner(): BelongsTo + { + return $this->belongsTo(User::class, 'owner_id'); + } + + /** + * Chapters within this project. + */ + public function chapters(): HasMany + { + return $this->hasMany(Chapter::class); + } + + /** + * Sections within this project via chapters. + */ + public function sections(): HasManyThrough + { + return $this->hasManyThrough(Section::class, Chapter::class, 'project_id', 'chapter_id'); + } + + /** + * Glossary entries defined for this project. + */ + public function glossaryEntries(): HasMany + { + return $this->hasMany(Glossary::class); + } + + /** + * Time blocks associated with this project. + */ + public function timeBlocks(): HasMany + { + return $this->hasMany(TimeBlock::class); + } + + /** + * Special criteria tied specifically to this project. + */ + public function specialCriteria(): HasMany + { + return $this->hasMany(Criterion::class, 'special_for_project_id'); + } } diff --git a/apps/backend/app/Models/Section.php b/apps/backend/app/Models/Section.php index 47ba4ad..38b1967 100644 --- a/apps/backend/app/Models/Section.php +++ b/apps/backend/app/Models/Section.php @@ -4,6 +4,8 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Support\Str; class Section extends Model @@ -31,4 +33,41 @@ protected static function booted() } }); } + + // Relationships + + public function chapter(): BelongsTo + { + return $this->belongsTo(Chapter::class); + } + + public function parent(): BelongsTo + { + return $this->belongsTo(Section::class, 'parent_id'); + } + + public function children(): HasMany + { + return $this->hasMany(Section::class, 'parent_id'); + } + + public function textBlocks(): HasMany + { + return $this->hasMany(TextBlock::class); + } + + public function images(): HasMany + { + return $this->hasMany(Image::class); + } + + public function tables(): HasMany + { + return $this->hasMany(Table::class); + } + + public function aiRatings(): HasMany + { + return $this->hasMany(AiRating::class); + } } diff --git a/apps/backend/app/Models/SubCriterion.php b/apps/backend/app/Models/SubCriterion.php index 7ac086e..a338ed8 100644 --- a/apps/backend/app/Models/SubCriterion.php +++ b/apps/backend/app/Models/SubCriterion.php @@ -4,6 +4,8 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Support\Str; class SubCriterion extends Model @@ -24,4 +26,16 @@ protected static function booted() } }); } + + // Relationships + + public function criterion(): BelongsTo + { + return $this->belongsTo(Criterion::class, 'criteria_id'); + } + + public function userSubCriteria(): HasMany + { + return $this->hasMany(UserSubCriterion::class, 'sub_criteria_id'); + } } diff --git a/apps/backend/app/Models/Table.php b/apps/backend/app/Models/Table.php index d771e4a..093fbbf 100644 --- a/apps/backend/app/Models/Table.php +++ b/apps/backend/app/Models/Table.php @@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Support\Str; class Table extends Model @@ -24,4 +25,11 @@ protected static function booted() } }); } + + // Relationships + + public function section(): BelongsTo + { + return $this->belongsTo(Section::class); + } } diff --git a/apps/backend/app/Models/TextBlock.php b/apps/backend/app/Models/TextBlock.php index 131ae19..d7bf2b8 100644 --- a/apps/backend/app/Models/TextBlock.php +++ b/apps/backend/app/Models/TextBlock.php @@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Support\Str; class TextBlock extends Model @@ -24,4 +25,11 @@ protected static function booted() } }); } + + // Relationships + + public function section(): BelongsTo + { + return $this->belongsTo(Section::class); + } } diff --git a/apps/backend/app/Models/TimeBlock.php b/apps/backend/app/Models/TimeBlock.php index fbb73cb..a3d8e74 100644 --- a/apps/backend/app/Models/TimeBlock.php +++ b/apps/backend/app/Models/TimeBlock.php @@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Support\Str; class TimeBlock extends Model @@ -24,4 +25,11 @@ protected static function booted() } }); } + + // Relationships + + public function project(): BelongsTo + { + return $this->belongsTo(Project::class); + } } diff --git a/apps/backend/app/Models/User.php b/apps/backend/app/Models/User.php index 02720c3..a4dc3e3 100644 --- a/apps/backend/app/Models/User.php +++ b/apps/backend/app/Models/User.php @@ -5,6 +5,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; +use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Support\Str; use Spatie\Permission\Traits\HasPermissions; use Spatie\Permission\Traits\HasRoles; @@ -49,4 +50,30 @@ public function getJWTCustomClaims() { return []; } + + // Relationships + + /** + * Projects owned by the user. + */ + public function projects(): HasMany + { + return $this->hasMany(Project::class, 'owner_id'); + } + + /** + * Additional metadata entries for the user. + */ + public function meta(): HasMany + { + return $this->hasMany(UserMeta::class); + } + + /** + * UserSubCriterion flags for this user. + */ + public function userSubCriteria(): HasMany + { + return $this->hasMany(UserSubCriterion::class); + } } diff --git a/apps/backend/app/Models/UserMeta.php b/apps/backend/app/Models/UserMeta.php index d47c758..8b3d48a 100644 --- a/apps/backend/app/Models/UserMeta.php +++ b/apps/backend/app/Models/UserMeta.php @@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Support\Str; class UserMeta extends Model @@ -24,4 +25,11 @@ protected static function booted() } }); } + + // Relationships + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } } diff --git a/apps/backend/app/Models/UserSubCriterion.php b/apps/backend/app/Models/UserSubCriterion.php index 8b29eb3..7aef268 100644 --- a/apps/backend/app/Models/UserSubCriterion.php +++ b/apps/backend/app/Models/UserSubCriterion.php @@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Support\Str; class UserSubCriterion extends Model @@ -24,4 +25,16 @@ protected static function booted() } }); } + + // Relationships + + public function subCriterion(): BelongsTo + { + return $this->belongsTo(SubCriterion::class, 'sub_criteria_id'); + } + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } } diff --git a/apps/backend/app/Models/Year.php b/apps/backend/app/Models/Year.php index 63f72f2..3ffaa92 100644 --- a/apps/backend/app/Models/Year.php +++ b/apps/backend/app/Models/Year.php @@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Support\Str; class Year extends Model @@ -24,4 +25,22 @@ protected static function booted() } }); } + + // Relationships + + /** + * Projects that belong to this year. + */ + public function projects(): HasMany + { + return $this->hasMany(Project::class); + } + + /** + * Criteria defined for this year. + */ + public function criteria(): HasMany + { + return $this->hasMany(Criterion::class); + } } From ccfc8986e346c306d42adf9a907cab1339f24fa3 Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 10:54:01 +0200 Subject: [PATCH 19/22] feat: output complete project data --- .../app/Http/Controllers/AppController.php | 36 ++++++++++++++++++ .../Http/Controllers/ProjectController.php | 37 ------------------- apps/backend/app/Models/Project.php | 9 +++++ apps/backend/routes/api.php | 7 ++-- 4 files changed, 48 insertions(+), 41 deletions(-) create mode 100644 apps/backend/app/Http/Controllers/AppController.php diff --git a/apps/backend/app/Http/Controllers/AppController.php b/apps/backend/app/Http/Controllers/AppController.php new file mode 100644 index 0000000..66b932d --- /dev/null +++ b/apps/backend/app/Http/Controllers/AppController.php @@ -0,0 +1,36 @@ +isOwnedByUser()) { + return response()->json(['message' => 'Forbidden'], 403); + } + + $project->load([ + 'chapters.sections' => function ($query) { + $query->with([ + 'children.textBlocks', + 'children.tables', + 'children.images', + 'children.children', + 'textBlocks', + 'tables', + 'images', + ]); + }, + ]); + + + return response()->json($project); + } +} \ No newline at end of file diff --git a/apps/backend/app/Http/Controllers/ProjectController.php b/apps/backend/app/Http/Controllers/ProjectController.php index b674cb7..206647a 100644 --- a/apps/backend/app/Http/Controllers/ProjectController.php +++ b/apps/backend/app/Http/Controllers/ProjectController.php @@ -38,41 +38,4 @@ public function delete(string $id) Project::findOrFail($id)->delete(); return response()->json(null, 204); } - - public function createProject(Request $request) - { - $validatedData = $request->validate([ - 'year_id' => 'required|exists:years,id', - 'owner_id' => 'required|exists:users,id', - 'name' => 'required|string|max:255', - 'start_date' => 'required|date', - 'end_date' => 'required|date|after_or_equal:start_date', - 'description' => 'nullable|string', - ]); - - $project = new Project($validatedData); - $project->save(); - - $new_project_id = $project->id; - - $defaultChapters = [ - ['name' => 'Ausführung und Resultat der Arbeit', 'type' => 'execution'], - ['name' => 'Dokumentation', 'type' => 'documentation'], - ['name' => 'Präsentation und Fachgespräch', 'type' => 'presentation'], - ]; - foreach ($defaultChapters as $chapterData) { - $chapter = new Chapter([ - 'project_id' => $new_project_id, - 'title' => $chapterData['name'], - 'type' => $chapterData['type'], - 'subtitle' => '', - ]); - $chapter->save(); - } - - return response()->json( - ['message' => 'Project created successfully', 'project' => $project], - 201, - ); - } } diff --git a/apps/backend/app/Models/Project.php b/apps/backend/app/Models/Project.php index 7d65828..d56a4c2 100644 --- a/apps/backend/app/Models/Project.php +++ b/apps/backend/app/Models/Project.php @@ -85,4 +85,13 @@ public function specialCriteria(): HasMany { return $this->hasMany(Criterion::class, 'special_for_project_id'); } + + public function isOwnedByUser() + { + if ($this->owner_id == auth()->user()['id']) { + return true; + } else { + return false; + } + } } diff --git a/apps/backend/routes/api.php b/apps/backend/routes/api.php index cf50145..7bd8374 100644 --- a/apps/backend/routes/api.php +++ b/apps/backend/routes/api.php @@ -3,7 +3,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; use App\Http\Controllers\AuthController; -use App\Http\Controllers\ProjectController; +use App\Http\Controllers\AppController; $tables = [ 'ai_ratings', @@ -64,11 +64,10 @@ }); } - Route::middleware('jwt') - ->prefix('project') + ->prefix('app') ->group(function () { - Route::post('/create', [ProjectController::class, 'createProject']); + Route::get('/projects/{project}', [AppController::class, 'getProject']); }); From 0f0092ad83f2a4a8a41a26eee261ba03f9bdf65a Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 11:06:38 +0200 Subject: [PATCH 20/22] refactor: for pushing :) --- .github/ISSUE_TEMPLATE/bug_report.md | 1 + .github/ISSUE_TEMPLATE/feature_request.md | 2 + .github/PULL_REQUEST_TEMPLATE.md | 4 ++ .prettierrc.cjs | 4 +- README.md | 2 +- apps/backend/docker-compose.yaml | 2 +- apps/backend/resources/css/app.css | 5 ++- apps/frontend/README.md | 2 +- docs/BRANCHING.md | 1 + eslint.config.cjs | 50 +++++++++++------------ 10 files changed, 41 insertions(+), 32 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 0e53326..f996574 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -3,6 +3,7 @@ name: Bug report about: Report a defect labels: bug --- + **Description** **Steps to Reproduce** **Expected / Actual** diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 56b886c..9aa9a5a 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -3,7 +3,9 @@ name: Feature request about: Propose an enhancement labels: enhancement --- + **Goal** **Scope** **Acceptance Criteria** + - [ ] ... diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1a2cd33..7924245 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,7 +1,11 @@ ## Purpose + ## Changes + - ... + ## Checks + - [ ] Lint ok - [ ] Prettier ok - [ ] Docs updated diff --git a/.prettierrc.cjs b/.prettierrc.cjs index 2b6ca87..936a8e3 100644 --- a/.prettierrc.cjs +++ b/.prettierrc.cjs @@ -1,7 +1,7 @@ module.exports = { printWidth: 100, singleQuote: true, - trailingComma: "all", + trailingComma: 'all', semi: true, - arrowParens: "always", + arrowParens: 'always', }; diff --git a/README.md b/README.md index 92ab1ce..ee13927 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,6 @@

Sesh is a mono-repo for managing PA/QV documentation. -It includes setup for **ESLint**, **Prettier**, **Husky hooks**, branching rules, GitHub workflows (CI/CD), and issue/PR templates. +It includes setup for **ESLint**, **Prettier**, **Husky hooks**, branching rules, GitHub workflows (CI/CD), and issue/PR templates. This serves as the foundation for future implementations (React/Laravel) with Keycloak integration. diff --git a/apps/backend/docker-compose.yaml b/apps/backend/docker-compose.yaml index 4627482..87c161a 100644 --- a/apps/backend/docker-compose.yaml +++ b/apps/backend/docker-compose.yaml @@ -9,7 +9,7 @@ services: MYSQL_USER: laravel MYSQL_PASSWORD: secret ports: - - "3306:3306" + - '3306:3306' volumes: - mariadb_data:/var/lib/mysql diff --git a/apps/backend/resources/css/app.css b/apps/backend/resources/css/app.css index 3e6abea..b85d4d2 100644 --- a/apps/backend/resources/css/app.css +++ b/apps/backend/resources/css/app.css @@ -6,6 +6,7 @@ @source '../**/*.js'; @theme { - --font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', - 'Segoe UI Symbol', 'Noto Color Emoji'; + --font-sans: + 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', + 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; } diff --git a/apps/frontend/README.md b/apps/frontend/README.md index 6d4ab91..60ac336 100644 --- a/apps/frontend/README.md +++ b/apps/frontend/README.md @@ -1 +1 @@ -Here will be the frontend \ No newline at end of file +Here will be the frontend diff --git a/docs/BRANCHING.md b/docs/BRANCHING.md index 26e66b9..87ada43 100644 --- a/docs/BRANCHING.md +++ b/docs/BRANCHING.md @@ -1,4 +1,5 @@ # Branching Rules + - Protected: main (PR only, squash, CI must pass) - Names: feat/-, fix/-, chore/... docs/... ci/... - PR: 1 review, lint & format green, short scope & checklist diff --git a/eslint.config.cjs b/eslint.config.cjs index 7617d47..61af56f 100644 --- a/eslint.config.cjs +++ b/eslint.config.cjs @@ -1,20 +1,20 @@ -const js = require("@eslint/js"); -const tseslint = require("typescript-eslint"); -const pluginImport = require("eslint-plugin-import"); +const js = require('@eslint/js'); +const tseslint = require('typescript-eslint'); +const pluginImport = require('eslint-plugin-import'); module.exports = [ // Global ignores (auch Prettier-/ESLint-Configs) { ignores: [ - "node_modules", - "dist", - "coverage", - "**/.eslintrc.*", - "**/.prettierrc.*", - "**/*.config.*", - ".husky/**", - ".github/**", - "docs/**" + 'node_modules', + 'dist', + 'coverage', + '**/.eslintrc.*', + '**/.prettierrc.*', + '**/*.config.*', + '.husky/**', + '.github/**', + 'docs/**', ], }, @@ -23,26 +23,26 @@ module.exports = [ // Standard-Regeln für Code { - files: ["**/*.{js,cjs,mjs,ts,tsx}"], - languageOptions: { ecmaVersion: "latest", sourceType: "module" }, + files: ['**/*.{js,cjs,mjs,ts,tsx}'], + languageOptions: { ecmaVersion: 'latest', sourceType: 'module' }, plugins: { import: pluginImport }, rules: { - "import/order": ["warn", { "newlines-between": "always" }], - "no-console": "off", - "@typescript-eslint/no-require-imports": "off" - } + 'import/order': ['warn', { 'newlines-between': 'always' }], + 'no-console': 'off', + '@typescript-eslint/no-require-imports': 'off', + }, }, // Sonderfall: eigene Config-Dateien im CJS-Stil { - files: ["eslint.config.cjs", "*.config.cjs", "*.config.js"], + files: ['eslint.config.cjs', '*.config.cjs', '*.config.js'], languageOptions: { - ecmaVersion: "latest", - sourceType: "commonjs", - globals: { module: "writable", require: "writable" } + ecmaVersion: 'latest', + sourceType: 'commonjs', + globals: { module: 'writable', require: 'writable' }, }, rules: { - "@typescript-eslint/no-require-imports": "off" - } - } + '@typescript-eslint/no-require-imports': 'off', + }, + }, ]; From fa21778e7538b7bde5bb04c78f8ca5f1482f294b Mon Sep 17 00:00:00 2001 From: Levin Zimmermann <111433435+RikoxCode@users.noreply.github.com> Date: Sat, 4 Oct 2025 11:21:46 +0200 Subject: [PATCH 21/22] Update apps/backend/database/migrations/2025_10_04_021216_create_roles_and_permissions.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../2025_10_04_021216_create_roles_and_permissions.php | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/backend/database/migrations/2025_10_04_021216_create_roles_and_permissions.php b/apps/backend/database/migrations/2025_10_04_021216_create_roles_and_permissions.php index 80cfefd..0d1046b 100644 --- a/apps/backend/database/migrations/2025_10_04_021216_create_roles_and_permissions.php +++ b/apps/backend/database/migrations/2025_10_04_021216_create_roles_and_permissions.php @@ -41,7 +41,6 @@ public function up(): void $view_users, $manage_years, $manage_criteria, - $manage_years, ); $admin_role->givePermissionTo(\App\Models\Permission::all()); } From 2405fa7b2e02478cc9a8e3e6f8b26b6df578ffcd Mon Sep 17 00:00:00 2001 From: utigernils Date: Sat, 4 Oct 2025 11:27:29 +0200 Subject: [PATCH 22/22] refactor: remove that stinky piece of shit --- apps/backend/composer.lock | 8770 ------------------------------------ 1 file changed, 8770 deletions(-) delete mode 100644 apps/backend/composer.lock diff --git a/apps/backend/composer.lock b/apps/backend/composer.lock deleted file mode 100644 index 9e157e7..0000000 --- a/apps/backend/composer.lock +++ /dev/null @@ -1,8770 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "e464c4dd898fe7d7d602dc2c39992ac2", - "packages": [ - { - "name": "brick/math", - "version": "0.14.0", - "source": { - "type": "git", - "url": "https://github.com/brick/math.git", - "reference": "113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2", - "reference": "113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2", - "shasum": "" - }, - "require": { - "php": "^8.2" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.2", - "phpstan/phpstan": "2.1.22", - "phpunit/phpunit": "^11.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Brick\\Math\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Arbitrary-precision arithmetic library", - "keywords": [ - "Arbitrary-precision", - "BigInteger", - "BigRational", - "arithmetic", - "bigdecimal", - "bignum", - "bignumber", - "brick", - "decimal", - "integer", - "math", - "mathematics", - "rational" - ], - "support": { - "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.14.0" - }, - "funding": [ - { - "url": "https://github.com/BenMorel", - "type": "github" - } - ], - "time": "2025-08-29T12:40:03+00:00" - }, - { - "name": "carbonphp/carbon-doctrine-types", - "version": "3.2.0", - "source": { - "type": "git", - "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git", - "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/18ba5ddfec8976260ead6e866180bd5d2f71aa1d", - "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d", - "shasum": "" - }, - "require": { - "php": "^8.1" - }, - "conflict": { - "doctrine/dbal": "<4.0.0 || >=5.0.0" - }, - "require-dev": { - "doctrine/dbal": "^4.0.0", - "nesbot/carbon": "^2.71.0 || ^3.0.0", - "phpunit/phpunit": "^10.3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Carbon\\Doctrine\\": "src/Carbon/Doctrine/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "KyleKatarn", - "email": "kylekatarnls@gmail.com" - } - ], - "description": "Types to use Carbon in Doctrine", - "keywords": [ - "carbon", - "date", - "datetime", - "doctrine", - "time" - ], - "support": { - "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", - "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0" - }, - "funding": [ - { - "url": "https://github.com/kylekatarnls", - "type": "github" - }, - { - "url": "https://opencollective.com/Carbon", - "type": "open_collective" - }, - { - "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", - "type": "tidelift" - } - ], - "time": "2024-02-09T16:56:22+00:00" - }, - { - "name": "dflydev/dot-access-data", - "version": "v3.0.3", - "source": { - "type": "git", - "url": "https://github.com/dflydev/dflydev-dot-access-data.git", - "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/a23a2bf4f31d3518f3ecb38660c95715dfead60f", - "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^0.12.42", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", - "scrutinizer/ocular": "1.6.0", - "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^4.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Dflydev\\DotAccessData\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dragonfly Development Inc.", - "email": "info@dflydev.com", - "homepage": "http://dflydev.com" - }, - { - "name": "Beau Simensen", - "email": "beau@dflydev.com", - "homepage": "http://beausimensen.com" - }, - { - "name": "Carlos Frutos", - "email": "carlos@kiwing.it", - "homepage": "https://github.com/cfrutos" - }, - { - "name": "Colin O'Dell", - "email": "colinodell@gmail.com", - "homepage": "https://www.colinodell.com" - } - ], - "description": "Given a deep data structure, access data by dot notation.", - "homepage": "https://github.com/dflydev/dflydev-dot-access-data", - "keywords": [ - "access", - "data", - "dot", - "notation" - ], - "support": { - "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", - "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.3" - }, - "time": "2024-07-08T12:26:09+00:00" - }, - { - "name": "doctrine/inflector", - "version": "2.1.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/inflector.git", - "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/6d6c96277ea252fc1304627204c3d5e6e15faa3b", - "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^12.0 || ^13.0", - "phpstan/phpstan": "^1.12 || ^2.0", - "phpstan/phpstan-phpunit": "^1.4 || ^2.0", - "phpstan/phpstan-strict-rules": "^1.6 || ^2.0", - "phpunit/phpunit": "^8.5 || ^12.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Inflector\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", - "homepage": "https://www.doctrine-project.org/projects/inflector.html", - "keywords": [ - "inflection", - "inflector", - "lowercase", - "manipulation", - "php", - "plural", - "singular", - "strings", - "uppercase", - "words" - ], - "support": { - "issues": "https://github.com/doctrine/inflector/issues", - "source": "https://github.com/doctrine/inflector/tree/2.1.0" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", - "type": "tidelift" - } - ], - "time": "2025-08-10T19:31:58+00:00" - }, - { - "name": "doctrine/lexer", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", - "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", - "shasum": "" - }, - "require": { - "php": "^8.1" - }, - "require-dev": { - "doctrine/coding-standard": "^12", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^10.5", - "psalm/plugin-phpunit": "^0.18.3", - "vimeo/psalm": "^5.21" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Lexer\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "https://www.doctrine-project.org/projects/lexer.html", - "keywords": [ - "annotations", - "docblock", - "lexer", - "parser", - "php" - ], - "support": { - "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/3.0.1" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", - "type": "tidelift" - } - ], - "time": "2024-02-05T11:56:58+00:00" - }, - { - "name": "dragonmantank/cron-expression", - "version": "v3.4.0", - "source": { - "type": "git", - "url": "https://github.com/dragonmantank/cron-expression.git", - "reference": "8c784d071debd117328803d86b2097615b457500" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/8c784d071debd117328803d86b2097615b457500", - "reference": "8c784d071debd117328803d86b2097615b457500", - "shasum": "" - }, - "require": { - "php": "^7.2|^8.0", - "webmozart/assert": "^1.0" - }, - "replace": { - "mtdowling/cron-expression": "^1.0" - }, - "require-dev": { - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.0", - "phpunit/phpunit": "^7.0|^8.0|^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Cron\\": "src/Cron/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Chris Tankersley", - "email": "chris@ctankersley.com", - "homepage": "https://github.com/dragonmantank" - } - ], - "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", - "keywords": [ - "cron", - "schedule" - ], - "support": { - "issues": "https://github.com/dragonmantank/cron-expression/issues", - "source": "https://github.com/dragonmantank/cron-expression/tree/v3.4.0" - }, - "funding": [ - { - "url": "https://github.com/dragonmantank", - "type": "github" - } - ], - "time": "2024-10-09T13:47:03+00:00" - }, - { - "name": "egulias/email-validator", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/egulias/EmailValidator.git", - "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", - "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", - "shasum": "" - }, - "require": { - "doctrine/lexer": "^2.0 || ^3.0", - "php": ">=8.1", - "symfony/polyfill-intl-idn": "^1.26" - }, - "require-dev": { - "phpunit/phpunit": "^10.2", - "vimeo/psalm": "^5.12" - }, - "suggest": { - "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Egulias\\EmailValidator\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eduardo Gulias Davis" - } - ], - "description": "A library for validating emails against several RFCs", - "homepage": "https://github.com/egulias/EmailValidator", - "keywords": [ - "email", - "emailvalidation", - "emailvalidator", - "validation", - "validator" - ], - "support": { - "issues": "https://github.com/egulias/EmailValidator/issues", - "source": "https://github.com/egulias/EmailValidator/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/egulias", - "type": "github" - } - ], - "time": "2025-03-06T22:45:56+00:00" - }, - { - "name": "fruitcake/php-cors", - "version": "v1.3.0", - "source": { - "type": "git", - "url": "https://github.com/fruitcake/php-cors.git", - "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/3d158f36e7875e2f040f37bc0573956240a5a38b", - "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b", - "shasum": "" - }, - "require": { - "php": "^7.4|^8.0", - "symfony/http-foundation": "^4.4|^5.4|^6|^7" - }, - "require-dev": { - "phpstan/phpstan": "^1.4", - "phpunit/phpunit": "^9", - "squizlabs/php_codesniffer": "^3.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2-dev" - } - }, - "autoload": { - "psr-4": { - "Fruitcake\\Cors\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fruitcake", - "homepage": "https://fruitcake.nl" - }, - { - "name": "Barryvdh", - "email": "barryvdh@gmail.com" - } - ], - "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", - "homepage": "https://github.com/fruitcake/php-cors", - "keywords": [ - "cors", - "laravel", - "symfony" - ], - "support": { - "issues": "https://github.com/fruitcake/php-cors/issues", - "source": "https://github.com/fruitcake/php-cors/tree/v1.3.0" - }, - "funding": [ - { - "url": "https://fruitcake.nl", - "type": "custom" - }, - { - "url": "https://github.com/barryvdh", - "type": "github" - } - ], - "time": "2023-10-12T05:21:21+00:00" - }, - { - "name": "graham-campbell/result-type", - "version": "v1.1.3", - "source": { - "type": "git", - "url": "https://github.com/GrahamCampbell/Result-Type.git", - "reference": "3ba905c11371512af9d9bdd27d99b782216b6945" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/3ba905c11371512af9d9bdd27d99b782216b6945", - "reference": "3ba905c11371512af9d9bdd27d99b782216b6945", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.3" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28" - }, - "type": "library", - "autoload": { - "psr-4": { - "GrahamCampbell\\ResultType\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - } - ], - "description": "An Implementation Of The Result Type", - "keywords": [ - "Graham Campbell", - "GrahamCampbell", - "Result Type", - "Result-Type", - "result" - ], - "support": { - "issues": "https://github.com/GrahamCampbell/Result-Type/issues", - "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.3" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", - "type": "tidelift" - } - ], - "time": "2024-07-20T21:45:45+00:00" - }, - { - "name": "guzzlehttp/guzzle", - "version": "7.10.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", - "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", - "shasum": "" - }, - "require": { - "ext-json": "*", - "guzzlehttp/promises": "^2.3", - "guzzlehttp/psr7": "^2.8", - "php": "^7.2.5 || ^8.0", - "psr/http-client": "^1.0", - "symfony/deprecation-contracts": "^2.2 || ^3.0" - }, - "provide": { - "psr/http-client-implementation": "1.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "ext-curl": "*", - "guzzle/client-integration-tests": "3.0.2", - "php-http/message-factory": "^1.1", - "phpunit/phpunit": "^8.5.39 || ^9.6.20", - "psr/log": "^1.1 || ^2.0 || ^3.0" - }, - "suggest": { - "ext-curl": "Required for CURL handler support", - "ext-intl": "Required for Internationalized Domain Name (IDN) support", - "psr/log": "Required for using the Log middleware" - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - } - }, - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "GuzzleHttp\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Jeremy Lindblom", - "email": "jeremeamia@gmail.com", - "homepage": "https://github.com/jeremeamia" - }, - { - "name": "George Mponos", - "email": "gmponos@gmail.com", - "homepage": "https://github.com/gmponos" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://github.com/sagikazarmark" - }, - { - "name": "Tobias Schultze", - "email": "webmaster@tubo-world.de", - "homepage": "https://github.com/Tobion" - } - ], - "description": "Guzzle is a PHP HTTP client library", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "psr-18", - "psr-7", - "rest", - "web service" - ], - "support": { - "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.10.0" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", - "type": "tidelift" - } - ], - "time": "2025-08-23T22:36:01+00:00" - }, - { - "name": "guzzlehttp/promises", - "version": "2.3.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "481557b130ef3790cf82b713667b43030dc9c957" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/481557b130ef3790cf82b713667b43030dc9c957", - "reference": "481557b130ef3790cf82b713667b43030dc9c957", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.44 || ^9.6.25" - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Tobias Schultze", - "email": "webmaster@tubo-world.de", - "homepage": "https://github.com/Tobion" - } - ], - "description": "Guzzle promises library", - "keywords": [ - "promise" - ], - "support": { - "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.3.0" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", - "type": "tidelift" - } - ], - "time": "2025-08-22T14:34:08+00:00" - }, - { - "name": "guzzlehttp/psr7", - "version": "2.8.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "21dc724a0583619cd1652f673303492272778051" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051", - "reference": "21dc724a0583619cd1652f673303492272778051", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.1 || ^2.0", - "ralouphie/getallheaders": "^3.0" - }, - "provide": { - "psr/http-factory-implementation": "1.0", - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "http-interop/http-factory-tests": "0.9.0", - "phpunit/phpunit": "^8.5.44 || ^9.6.25" - }, - "suggest": { - "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "George Mponos", - "email": "gmponos@gmail.com", - "homepage": "https://github.com/gmponos" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://github.com/sagikazarmark" - }, - { - "name": "Tobias Schultze", - "email": "webmaster@tubo-world.de", - "homepage": "https://github.com/Tobion" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://sagikazarmark.hu" - } - ], - "description": "PSR-7 message implementation that also provides common utility methods", - "keywords": [ - "http", - "message", - "psr-7", - "request", - "response", - "stream", - "uri", - "url" - ], - "support": { - "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.8.0" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", - "type": "tidelift" - } - ], - "time": "2025-08-23T21:21:41+00:00" - }, - { - "name": "guzzlehttp/uri-template", - "version": "v1.0.5", - "source": { - "type": "git", - "url": "https://github.com/guzzle/uri-template.git", - "reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/uri-template/zipball/4f4bbd4e7172148801e76e3decc1e559bdee34e1", - "reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0", - "symfony/polyfill-php80": "^1.24" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.44 || ^9.6.25", - "uri-template/tests": "1.0.0" - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\UriTemplate\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "George Mponos", - "email": "gmponos@gmail.com", - "homepage": "https://github.com/gmponos" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - } - ], - "description": "A polyfill class for uri_template of PHP", - "keywords": [ - "guzzlehttp", - "uri-template" - ], - "support": { - "issues": "https://github.com/guzzle/uri-template/issues", - "source": "https://github.com/guzzle/uri-template/tree/v1.0.5" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/uri-template", - "type": "tidelift" - } - ], - "time": "2025-08-22T14:27:06+00:00" - }, - { - "name": "laravel/framework", - "version": "v12.32.5", - "source": { - "type": "git", - "url": "https://github.com/laravel/framework.git", - "reference": "77b2740391cd2a825ba59d6fada45e9b8b9bcc5a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/77b2740391cd2a825ba59d6fada45e9b8b9bcc5a", - "reference": "77b2740391cd2a825ba59d6fada45e9b8b9bcc5a", - "shasum": "" - }, - "require": { - "brick/math": "^0.11|^0.12|^0.13|^0.14", - "composer-runtime-api": "^2.2", - "doctrine/inflector": "^2.0.5", - "dragonmantank/cron-expression": "^3.4", - "egulias/email-validator": "^3.2.1|^4.0", - "ext-ctype": "*", - "ext-filter": "*", - "ext-hash": "*", - "ext-mbstring": "*", - "ext-openssl": "*", - "ext-session": "*", - "ext-tokenizer": "*", - "fruitcake/php-cors": "^1.3", - "guzzlehttp/guzzle": "^7.8.2", - "guzzlehttp/uri-template": "^1.0", - "laravel/prompts": "^0.3.0", - "laravel/serializable-closure": "^1.3|^2.0", - "league/commonmark": "^2.7", - "league/flysystem": "^3.25.1", - "league/flysystem-local": "^3.25.1", - "league/uri": "^7.5.1", - "monolog/monolog": "^3.0", - "nesbot/carbon": "^3.8.4", - "nunomaduro/termwind": "^2.0", - "php": "^8.2", - "psr/container": "^1.1.1|^2.0.1", - "psr/log": "^1.0|^2.0|^3.0", - "psr/simple-cache": "^1.0|^2.0|^3.0", - "ramsey/uuid": "^4.7", - "symfony/console": "^7.2.0", - "symfony/error-handler": "^7.2.0", - "symfony/finder": "^7.2.0", - "symfony/http-foundation": "^7.2.0", - "symfony/http-kernel": "^7.2.0", - "symfony/mailer": "^7.2.0", - "symfony/mime": "^7.2.0", - "symfony/polyfill-php83": "^1.33", - "symfony/polyfill-php84": "^1.33", - "symfony/polyfill-php85": "^1.33", - "symfony/process": "^7.2.0", - "symfony/routing": "^7.2.0", - "symfony/uid": "^7.2.0", - "symfony/var-dumper": "^7.2.0", - "tijsverkoyen/css-to-inline-styles": "^2.2.5", - "vlucas/phpdotenv": "^5.6.1", - "voku/portable-ascii": "^2.0.2" - }, - "conflict": { - "tightenco/collect": "<5.5.33" - }, - "provide": { - "psr/container-implementation": "1.1|2.0", - "psr/log-implementation": "1.0|2.0|3.0", - "psr/simple-cache-implementation": "1.0|2.0|3.0" - }, - "replace": { - "illuminate/auth": "self.version", - "illuminate/broadcasting": "self.version", - "illuminate/bus": "self.version", - "illuminate/cache": "self.version", - "illuminate/collections": "self.version", - "illuminate/concurrency": "self.version", - "illuminate/conditionable": "self.version", - "illuminate/config": "self.version", - "illuminate/console": "self.version", - "illuminate/container": "self.version", - "illuminate/contracts": "self.version", - "illuminate/cookie": "self.version", - "illuminate/database": "self.version", - "illuminate/encryption": "self.version", - "illuminate/events": "self.version", - "illuminate/filesystem": "self.version", - "illuminate/hashing": "self.version", - "illuminate/http": "self.version", - "illuminate/json-schema": "self.version", - "illuminate/log": "self.version", - "illuminate/macroable": "self.version", - "illuminate/mail": "self.version", - "illuminate/notifications": "self.version", - "illuminate/pagination": "self.version", - "illuminate/pipeline": "self.version", - "illuminate/process": "self.version", - "illuminate/queue": "self.version", - "illuminate/redis": "self.version", - "illuminate/routing": "self.version", - "illuminate/session": "self.version", - "illuminate/support": "self.version", - "illuminate/testing": "self.version", - "illuminate/translation": "self.version", - "illuminate/validation": "self.version", - "illuminate/view": "self.version", - "spatie/once": "*" - }, - "require-dev": { - "ably/ably-php": "^1.0", - "aws/aws-sdk-php": "^3.322.9", - "ext-gmp": "*", - "fakerphp/faker": "^1.24", - "guzzlehttp/promises": "^2.0.3", - "guzzlehttp/psr7": "^2.4", - "laravel/pint": "^1.18", - "league/flysystem-aws-s3-v3": "^3.25.1", - "league/flysystem-ftp": "^3.25.1", - "league/flysystem-path-prefixing": "^3.25.1", - "league/flysystem-read-only": "^3.25.1", - "league/flysystem-sftp-v3": "^3.25.1", - "mockery/mockery": "^1.6.10", - "opis/json-schema": "^2.4.1", - "orchestra/testbench-core": "^10.6.5", - "pda/pheanstalk": "^5.0.6|^7.0.0", - "php-http/discovery": "^1.15", - "phpstan/phpstan": "^2.0", - "phpunit/phpunit": "^10.5.35|^11.5.3|^12.0.1", - "predis/predis": "^2.3|^3.0", - "resend/resend-php": "^0.10.0", - "symfony/cache": "^7.2.0", - "symfony/http-client": "^7.2.0", - "symfony/psr-http-message-bridge": "^7.2.0", - "symfony/translation": "^7.2.0" - }, - "suggest": { - "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", - "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.322.9).", - "brianium/paratest": "Required to run tests in parallel (^7.0|^8.0).", - "ext-apcu": "Required to use the APC cache driver.", - "ext-fileinfo": "Required to use the Filesystem class.", - "ext-ftp": "Required to use the Flysystem FTP driver.", - "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", - "ext-memcached": "Required to use the memcache cache driver.", - "ext-pcntl": "Required to use all features of the queue worker and console signal trapping.", - "ext-pdo": "Required to use all database features.", - "ext-posix": "Required to use all features of the queue worker.", - "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0|^6.0).", - "fakerphp/faker": "Required to generate fake data using the fake() helper (^1.23).", - "filp/whoops": "Required for friendly error pages in development (^2.14.3).", - "laravel/tinker": "Required to use the tinker console command (^2.0).", - "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.25.1).", - "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.25.1).", - "league/flysystem-path-prefixing": "Required to use the scoped driver (^3.25.1).", - "league/flysystem-read-only": "Required to use read-only disks (^3.25.1)", - "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.25.1).", - "mockery/mockery": "Required to use mocking (^1.6).", - "pda/pheanstalk": "Required to use the beanstalk queue driver (^5.0).", - "php-http/discovery": "Required to use PSR-7 bridging features (^1.15).", - "phpunit/phpunit": "Required to use assertions and run tests (^10.5.35|^11.5.3|^12.0.1).", - "predis/predis": "Required to use the predis connector (^2.3|^3.0).", - "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", - "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", - "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0).", - "symfony/cache": "Required to PSR-6 cache bridge (^7.2).", - "symfony/filesystem": "Required to enable support for relative symbolic links (^7.2).", - "symfony/http-client": "Required to enable support for the Symfony API mail transports (^7.2).", - "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.2).", - "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.2).", - "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.2)." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "12.x-dev" - } - }, - "autoload": { - "files": [ - "src/Illuminate/Collections/functions.php", - "src/Illuminate/Collections/helpers.php", - "src/Illuminate/Events/functions.php", - "src/Illuminate/Filesystem/functions.php", - "src/Illuminate/Foundation/helpers.php", - "src/Illuminate/Log/functions.php", - "src/Illuminate/Support/functions.php", - "src/Illuminate/Support/helpers.php" - ], - "psr-4": { - "Illuminate\\": "src/Illuminate/", - "Illuminate\\Support\\": [ - "src/Illuminate/Macroable/", - "src/Illuminate/Collections/", - "src/Illuminate/Conditionable/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "The Laravel Framework.", - "homepage": "https://laravel.com", - "keywords": [ - "framework", - "laravel" - ], - "support": { - "issues": "https://github.com/laravel/framework/issues", - "source": "https://github.com/laravel/framework" - }, - "time": "2025-09-30T17:39:22+00:00" - }, - { - "name": "laravel/prompts", - "version": "v0.3.7", - "source": { - "type": "git", - "url": "https://github.com/laravel/prompts.git", - "reference": "a1891d362714bc40c8d23b0b1d7090f022ea27cc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/prompts/zipball/a1891d362714bc40c8d23b0b1d7090f022ea27cc", - "reference": "a1891d362714bc40c8d23b0b1d7090f022ea27cc", - "shasum": "" - }, - "require": { - "composer-runtime-api": "^2.2", - "ext-mbstring": "*", - "php": "^8.1", - "symfony/console": "^6.2|^7.0" - }, - "conflict": { - "illuminate/console": ">=10.17.0 <10.25.0", - "laravel/framework": ">=10.17.0 <10.25.0" - }, - "require-dev": { - "illuminate/collections": "^10.0|^11.0|^12.0", - "mockery/mockery": "^1.5", - "pestphp/pest": "^2.3|^3.4", - "phpstan/phpstan": "^1.12.28", - "phpstan/phpstan-mockery": "^1.1.3" - }, - "suggest": { - "ext-pcntl": "Required for the spinner to be animated." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "0.3.x-dev" - } - }, - "autoload": { - "files": [ - "src/helpers.php" - ], - "psr-4": { - "Laravel\\Prompts\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Add beautiful and user-friendly forms to your command-line applications.", - "support": { - "issues": "https://github.com/laravel/prompts/issues", - "source": "https://github.com/laravel/prompts/tree/v0.3.7" - }, - "time": "2025-09-19T13:47:56+00:00" - }, - { - "name": "laravel/sanctum", - "version": "v4.2.0", - "source": { - "type": "git", - "url": "https://github.com/laravel/sanctum.git", - "reference": "fd6df4f79f48a72992e8d29a9c0ee25422a0d677" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/sanctum/zipball/fd6df4f79f48a72992e8d29a9c0ee25422a0d677", - "reference": "fd6df4f79f48a72992e8d29a9c0ee25422a0d677", - "shasum": "" - }, - "require": { - "ext-json": "*", - "illuminate/console": "^11.0|^12.0", - "illuminate/contracts": "^11.0|^12.0", - "illuminate/database": "^11.0|^12.0", - "illuminate/support": "^11.0|^12.0", - "php": "^8.2", - "symfony/console": "^7.0" - }, - "require-dev": { - "mockery/mockery": "^1.6", - "orchestra/testbench": "^9.0|^10.0", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^11.3" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Laravel\\Sanctum\\SanctumServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Laravel\\Sanctum\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.", - "keywords": [ - "auth", - "laravel", - "sanctum" - ], - "support": { - "issues": "https://github.com/laravel/sanctum/issues", - "source": "https://github.com/laravel/sanctum" - }, - "time": "2025-07-09T19:45:24+00:00" - }, - { - "name": "laravel/serializable-closure", - "version": "v2.0.5", - "source": { - "type": "git", - "url": "https://github.com/laravel/serializable-closure.git", - "reference": "3832547db6e0e2f8bb03d4093857b378c66eceed" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/3832547db6e0e2f8bb03d4093857b378c66eceed", - "reference": "3832547db6e0e2f8bb03d4093857b378c66eceed", - "shasum": "" - }, - "require": { - "php": "^8.1" - }, - "require-dev": { - "illuminate/support": "^10.0|^11.0|^12.0", - "nesbot/carbon": "^2.67|^3.0", - "pestphp/pest": "^2.36|^3.0", - "phpstan/phpstan": "^2.0", - "symfony/var-dumper": "^6.2.0|^7.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "Laravel\\SerializableClosure\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - }, - { - "name": "Nuno Maduro", - "email": "nuno@laravel.com" - } - ], - "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", - "keywords": [ - "closure", - "laravel", - "serializable" - ], - "support": { - "issues": "https://github.com/laravel/serializable-closure/issues", - "source": "https://github.com/laravel/serializable-closure" - }, - "time": "2025-09-22T17:29:40+00:00" - }, - { - "name": "laravel/tinker", - "version": "v2.10.1", - "source": { - "type": "git", - "url": "https://github.com/laravel/tinker.git", - "reference": "22177cc71807d38f2810c6204d8f7183d88a57d3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/tinker/zipball/22177cc71807d38f2810c6204d8f7183d88a57d3", - "reference": "22177cc71807d38f2810c6204d8f7183d88a57d3", - "shasum": "" - }, - "require": { - "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", - "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", - "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", - "php": "^7.2.5|^8.0", - "psy/psysh": "^0.11.1|^0.12.0", - "symfony/var-dumper": "^4.3.4|^5.0|^6.0|^7.0" - }, - "require-dev": { - "mockery/mockery": "~1.3.3|^1.4.2", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^8.5.8|^9.3.3|^10.0" - }, - "suggest": { - "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0)." - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Laravel\\Tinker\\TinkerServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Laravel\\Tinker\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "Powerful REPL for the Laravel framework.", - "keywords": [ - "REPL", - "Tinker", - "laravel", - "psysh" - ], - "support": { - "issues": "https://github.com/laravel/tinker/issues", - "source": "https://github.com/laravel/tinker/tree/v2.10.1" - }, - "time": "2025-01-27T14:24:01+00:00" - }, - { - "name": "lcobucci/clock", - "version": "3.3.1", - "source": { - "type": "git", - "url": "https://github.com/lcobucci/clock.git", - "reference": "db3713a61addfffd615b79bf0bc22f0ccc61b86b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/lcobucci/clock/zipball/db3713a61addfffd615b79bf0bc22f0ccc61b86b", - "reference": "db3713a61addfffd615b79bf0bc22f0ccc61b86b", - "shasum": "" - }, - "require": { - "php": "~8.2.0 || ~8.3.0 || ~8.4.0", - "psr/clock": "^1.0" - }, - "provide": { - "psr/clock-implementation": "1.0" - }, - "require-dev": { - "infection/infection": "^0.29", - "lcobucci/coding-standard": "^11.1.0", - "phpstan/extension-installer": "^1.3.1", - "phpstan/phpstan": "^1.10.25", - "phpstan/phpstan-deprecation-rules": "^1.1.3", - "phpstan/phpstan-phpunit": "^1.3.13", - "phpstan/phpstan-strict-rules": "^1.5.1", - "phpunit/phpunit": "^11.3.6" - }, - "type": "library", - "autoload": { - "psr-4": { - "Lcobucci\\Clock\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Luís Cobucci", - "email": "lcobucci@gmail.com" - } - ], - "description": "Yet another clock abstraction", - "support": { - "issues": "https://github.com/lcobucci/clock/issues", - "source": "https://github.com/lcobucci/clock/tree/3.3.1" - }, - "funding": [ - { - "url": "https://github.com/lcobucci", - "type": "github" - }, - { - "url": "https://www.patreon.com/lcobucci", - "type": "patreon" - } - ], - "time": "2024-09-24T20:45:14+00:00" - }, - { - "name": "lcobucci/jwt", - "version": "4.3.0", - "source": { - "type": "git", - "url": "https://github.com/lcobucci/jwt.git", - "reference": "4d7de2fe0d51a96418c0d04004986e410e87f6b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/lcobucci/jwt/zipball/4d7de2fe0d51a96418c0d04004986e410e87f6b4", - "reference": "4d7de2fe0d51a96418c0d04004986e410e87f6b4", - "shasum": "" - }, - "require": { - "ext-hash": "*", - "ext-json": "*", - "ext-mbstring": "*", - "ext-openssl": "*", - "ext-sodium": "*", - "lcobucci/clock": "^2.0 || ^3.0", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "infection/infection": "^0.21", - "lcobucci/coding-standard": "^6.0", - "mikey179/vfsstream": "^1.6.7", - "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-phpunit": "^1.0", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/php-invoker": "^3.1", - "phpunit/phpunit": "^9.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Lcobucci\\JWT\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Luís Cobucci", - "email": "lcobucci@gmail.com", - "role": "Developer" - } - ], - "description": "A simple library to work with JSON Web Token and JSON Web Signature", - "keywords": [ - "JWS", - "jwt" - ], - "support": { - "issues": "https://github.com/lcobucci/jwt/issues", - "source": "https://github.com/lcobucci/jwt/tree/4.3.0" - }, - "funding": [ - { - "url": "https://github.com/lcobucci", - "type": "github" - }, - { - "url": "https://www.patreon.com/lcobucci", - "type": "patreon" - } - ], - "time": "2023-01-02T13:28:00+00:00" - }, - { - "name": "league/commonmark", - "version": "2.7.1", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/commonmark.git", - "reference": "10732241927d3971d28e7ea7b5712721fa2296ca" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/10732241927d3971d28e7ea7b5712721fa2296ca", - "reference": "10732241927d3971d28e7ea7b5712721fa2296ca", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "league/config": "^1.1.1", - "php": "^7.4 || ^8.0", - "psr/event-dispatcher": "^1.0", - "symfony/deprecation-contracts": "^2.1 || ^3.0", - "symfony/polyfill-php80": "^1.16" - }, - "require-dev": { - "cebe/markdown": "^1.0", - "commonmark/cmark": "0.31.1", - "commonmark/commonmark.js": "0.31.1", - "composer/package-versions-deprecated": "^1.8", - "embed/embed": "^4.4", - "erusev/parsedown": "^1.0", - "ext-json": "*", - "github/gfm": "0.29.0", - "michelf/php-markdown": "^1.4 || ^2.0", - "nyholm/psr7": "^1.5", - "phpstan/phpstan": "^1.8.2", - "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0", - "scrutinizer/ocular": "^1.8.1", - "symfony/finder": "^5.3 | ^6.0 | ^7.0", - "symfony/process": "^5.4 | ^6.0 | ^7.0", - "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0", - "unleashedtech/php-coding-standard": "^3.1.1", - "vimeo/psalm": "^4.24.0 || ^5.0.0 || ^6.0.0" - }, - "suggest": { - "symfony/yaml": "v2.3+ required if using the Front Matter extension" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.8-dev" - } - }, - "autoload": { - "psr-4": { - "League\\CommonMark\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Colin O'Dell", - "email": "colinodell@gmail.com", - "homepage": "https://www.colinodell.com", - "role": "Lead Developer" - } - ], - "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", - "homepage": "https://commonmark.thephpleague.com", - "keywords": [ - "commonmark", - "flavored", - "gfm", - "github", - "github-flavored", - "markdown", - "md", - "parser" - ], - "support": { - "docs": "https://commonmark.thephpleague.com/", - "forum": "https://github.com/thephpleague/commonmark/discussions", - "issues": "https://github.com/thephpleague/commonmark/issues", - "rss": "https://github.com/thephpleague/commonmark/releases.atom", - "source": "https://github.com/thephpleague/commonmark" - }, - "funding": [ - { - "url": "https://www.colinodell.com/sponsor", - "type": "custom" - }, - { - "url": "https://www.paypal.me/colinpodell/10.00", - "type": "custom" - }, - { - "url": "https://github.com/colinodell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/league/commonmark", - "type": "tidelift" - } - ], - "time": "2025-07-20T12:47:49+00:00" - }, - { - "name": "league/config", - "version": "v1.2.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/config.git", - "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", - "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", - "shasum": "" - }, - "require": { - "dflydev/dot-access-data": "^3.0.1", - "nette/schema": "^1.2", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.8.2", - "phpunit/phpunit": "^9.5.5", - "scrutinizer/ocular": "^1.8.1", - "unleashedtech/php-coding-standard": "^3.1", - "vimeo/psalm": "^4.7.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.2-dev" - } - }, - "autoload": { - "psr-4": { - "League\\Config\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Colin O'Dell", - "email": "colinodell@gmail.com", - "homepage": "https://www.colinodell.com", - "role": "Lead Developer" - } - ], - "description": "Define configuration arrays with strict schemas and access values with dot notation", - "homepage": "https://config.thephpleague.com", - "keywords": [ - "array", - "config", - "configuration", - "dot", - "dot-access", - "nested", - "schema" - ], - "support": { - "docs": "https://config.thephpleague.com/", - "issues": "https://github.com/thephpleague/config/issues", - "rss": "https://github.com/thephpleague/config/releases.atom", - "source": "https://github.com/thephpleague/config" - }, - "funding": [ - { - "url": "https://www.colinodell.com/sponsor", - "type": "custom" - }, - { - "url": "https://www.paypal.me/colinpodell/10.00", - "type": "custom" - }, - { - "url": "https://github.com/colinodell", - "type": "github" - } - ], - "time": "2022-12-11T20:36:23+00:00" - }, - { - "name": "league/flysystem", - "version": "3.30.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/flysystem.git", - "reference": "2203e3151755d874bb2943649dae1eb8533ac93e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/2203e3151755d874bb2943649dae1eb8533ac93e", - "reference": "2203e3151755d874bb2943649dae1eb8533ac93e", - "shasum": "" - }, - "require": { - "league/flysystem-local": "^3.0.0", - "league/mime-type-detection": "^1.0.0", - "php": "^8.0.2" - }, - "conflict": { - "async-aws/core": "<1.19.0", - "async-aws/s3": "<1.14.0", - "aws/aws-sdk-php": "3.209.31 || 3.210.0", - "guzzlehttp/guzzle": "<7.0", - "guzzlehttp/ringphp": "<1.1.1", - "phpseclib/phpseclib": "3.0.15", - "symfony/http-client": "<5.2" - }, - "require-dev": { - "async-aws/s3": "^1.5 || ^2.0", - "async-aws/simple-s3": "^1.1 || ^2.0", - "aws/aws-sdk-php": "^3.295.10", - "composer/semver": "^3.0", - "ext-fileinfo": "*", - "ext-ftp": "*", - "ext-mongodb": "^1.3|^2", - "ext-zip": "*", - "friendsofphp/php-cs-fixer": "^3.5", - "google/cloud-storage": "^1.23", - "guzzlehttp/psr7": "^2.6", - "microsoft/azure-storage-blob": "^1.1", - "mongodb/mongodb": "^1.2|^2", - "phpseclib/phpseclib": "^3.0.36", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^9.5.11|^10.0", - "sabre/dav": "^4.6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "League\\Flysystem\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Frank de Jonge", - "email": "info@frankdejonge.nl" - } - ], - "description": "File storage abstraction for PHP", - "keywords": [ - "WebDAV", - "aws", - "cloud", - "file", - "files", - "filesystem", - "filesystems", - "ftp", - "s3", - "sftp", - "storage" - ], - "support": { - "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.30.0" - }, - "time": "2025-06-25T13:29:59+00:00" - }, - { - "name": "league/flysystem-local", - "version": "3.30.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/flysystem-local.git", - "reference": "6691915f77c7fb69adfb87dcd550052dc184ee10" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/6691915f77c7fb69adfb87dcd550052dc184ee10", - "reference": "6691915f77c7fb69adfb87dcd550052dc184ee10", - "shasum": "" - }, - "require": { - "ext-fileinfo": "*", - "league/flysystem": "^3.0.0", - "league/mime-type-detection": "^1.0.0", - "php": "^8.0.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "League\\Flysystem\\Local\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Frank de Jonge", - "email": "info@frankdejonge.nl" - } - ], - "description": "Local filesystem adapter for Flysystem.", - "keywords": [ - "Flysystem", - "file", - "files", - "filesystem", - "local" - ], - "support": { - "source": "https://github.com/thephpleague/flysystem-local/tree/3.30.0" - }, - "time": "2025-05-21T10:34:19+00:00" - }, - { - "name": "league/mime-type-detection", - "version": "1.16.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/2d6702ff215bf922936ccc1ad31007edc76451b9", - "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9", - "shasum": "" - }, - "require": { - "ext-fileinfo": "*", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.2", - "phpstan/phpstan": "^0.12.68", - "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "League\\MimeTypeDetection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Frank de Jonge", - "email": "info@frankdejonge.nl" - } - ], - "description": "Mime-type detection for Flysystem", - "support": { - "issues": "https://github.com/thephpleague/mime-type-detection/issues", - "source": "https://github.com/thephpleague/mime-type-detection/tree/1.16.0" - }, - "funding": [ - { - "url": "https://github.com/frankdejonge", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/league/flysystem", - "type": "tidelift" - } - ], - "time": "2024-09-21T08:32:55+00:00" - }, - { - "name": "league/uri", - "version": "7.5.1", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/uri.git", - "reference": "81fb5145d2644324614cc532b28efd0215bda430" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/81fb5145d2644324614cc532b28efd0215bda430", - "reference": "81fb5145d2644324614cc532b28efd0215bda430", - "shasum": "" - }, - "require": { - "league/uri-interfaces": "^7.5", - "php": "^8.1" - }, - "conflict": { - "league/uri-schemes": "^1.0" - }, - "suggest": { - "ext-bcmath": "to improve IPV4 host parsing", - "ext-fileinfo": "to create Data URI from file contennts", - "ext-gmp": "to improve IPV4 host parsing", - "ext-intl": "to handle IDN host with the best performance", - "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain", - "league/uri-components": "Needed to easily manipulate URI objects components", - "php-64bit": "to improve IPV4 host parsing", - "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "7.x-dev" - } - }, - "autoload": { - "psr-4": { - "League\\Uri\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ignace Nyamagana Butera", - "email": "nyamsprod@gmail.com", - "homepage": "https://nyamsprod.com" - } - ], - "description": "URI manipulation library", - "homepage": "https://uri.thephpleague.com", - "keywords": [ - "data-uri", - "file-uri", - "ftp", - "hostname", - "http", - "https", - "middleware", - "parse_str", - "parse_url", - "psr-7", - "query-string", - "querystring", - "rfc3986", - "rfc3987", - "rfc6570", - "uri", - "uri-template", - "url", - "ws" - ], - "support": { - "docs": "https://uri.thephpleague.com", - "forum": "https://thephpleague.slack.com", - "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri/tree/7.5.1" - }, - "funding": [ - { - "url": "https://github.com/sponsors/nyamsprod", - "type": "github" - } - ], - "time": "2024-12-08T08:40:02+00:00" - }, - { - "name": "league/uri-interfaces", - "version": "7.5.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/uri-interfaces.git", - "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", - "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^8.1", - "psr/http-factory": "^1", - "psr/http-message": "^1.1 || ^2.0" - }, - "suggest": { - "ext-bcmath": "to improve IPV4 host parsing", - "ext-gmp": "to improve IPV4 host parsing", - "ext-intl": "to handle IDN host with the best performance", - "php-64bit": "to improve IPV4 host parsing", - "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "7.x-dev" - } - }, - "autoload": { - "psr-4": { - "League\\Uri\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ignace Nyamagana Butera", - "email": "nyamsprod@gmail.com", - "homepage": "https://nyamsprod.com" - } - ], - "description": "Common interfaces and classes for URI representation and interaction", - "homepage": "https://uri.thephpleague.com", - "keywords": [ - "data-uri", - "file-uri", - "ftp", - "hostname", - "http", - "https", - "parse_str", - "parse_url", - "psr-7", - "query-string", - "querystring", - "rfc3986", - "rfc3987", - "rfc6570", - "uri", - "url", - "ws" - ], - "support": { - "docs": "https://uri.thephpleague.com", - "forum": "https://thephpleague.slack.com", - "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri-interfaces/tree/7.5.0" - }, - "funding": [ - { - "url": "https://github.com/sponsors/nyamsprod", - "type": "github" - } - ], - "time": "2024-12-08T08:18:47+00:00" - }, - { - "name": "monolog/monolog", - "version": "3.9.0", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/monolog.git", - "reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/10d85740180ecba7896c87e06a166e0c95a0e3b6", - "reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "psr/log": "^2.0 || ^3.0" - }, - "provide": { - "psr/log-implementation": "3.0.0" - }, - "require-dev": { - "aws/aws-sdk-php": "^3.0", - "doctrine/couchdb": "~1.0@dev", - "elasticsearch/elasticsearch": "^7 || ^8", - "ext-json": "*", - "graylog2/gelf-php": "^1.4.2 || ^2.0", - "guzzlehttp/guzzle": "^7.4.5", - "guzzlehttp/psr7": "^2.2", - "mongodb/mongodb": "^1.8", - "php-amqplib/php-amqplib": "~2.4 || ^3", - "php-console/php-console": "^3.1.8", - "phpstan/phpstan": "^2", - "phpstan/phpstan-deprecation-rules": "^2", - "phpstan/phpstan-strict-rules": "^2", - "phpunit/phpunit": "^10.5.17 || ^11.0.7", - "predis/predis": "^1.1 || ^2", - "rollbar/rollbar": "^4.0", - "ruflin/elastica": "^7 || ^8", - "symfony/mailer": "^5.4 || ^6", - "symfony/mime": "^5.4 || ^6" - }, - "suggest": { - "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", - "doctrine/couchdb": "Allow sending log messages to a CouchDB server", - "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", - "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", - "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", - "ext-mbstring": "Allow to work properly with unicode symbols", - "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", - "ext-openssl": "Required to send log messages using SSL", - "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", - "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", - "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", - "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", - "rollbar/rollbar": "Allow sending log messages to Rollbar", - "ruflin/elastica": "Allow sending log messages to an Elastic Search server" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Monolog\\": "src/Monolog" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "https://seld.be" - } - ], - "description": "Sends your logs to files, sockets, inboxes, databases and various web services", - "homepage": "https://github.com/Seldaek/monolog", - "keywords": [ - "log", - "logging", - "psr-3" - ], - "support": { - "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/3.9.0" - }, - "funding": [ - { - "url": "https://github.com/Seldaek", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", - "type": "tidelift" - } - ], - "time": "2025-03-24T10:02:05+00:00" - }, - { - "name": "nesbot/carbon", - "version": "3.10.3", - "source": { - "type": "git", - "url": "https://github.com/CarbonPHP/carbon.git", - "reference": "8e3643dcd149ae0fe1d2ff4f2c8e4bbfad7c165f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/8e3643dcd149ae0fe1d2ff4f2c8e4bbfad7c165f", - "reference": "8e3643dcd149ae0fe1d2ff4f2c8e4bbfad7c165f", - "shasum": "" - }, - "require": { - "carbonphp/carbon-doctrine-types": "<100.0", - "ext-json": "*", - "php": "^8.1", - "psr/clock": "^1.0", - "symfony/clock": "^6.3.12 || ^7.0", - "symfony/polyfill-mbstring": "^1.0", - "symfony/translation": "^4.4.18 || ^5.2.1 || ^6.0 || ^7.0" - }, - "provide": { - "psr/clock-implementation": "1.0" - }, - "require-dev": { - "doctrine/dbal": "^3.6.3 || ^4.0", - "doctrine/orm": "^2.15.2 || ^3.0", - "friendsofphp/php-cs-fixer": "^v3.87.1", - "kylekatarnls/multi-tester": "^2.5.3", - "phpmd/phpmd": "^2.15.0", - "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^2.1.22", - "phpunit/phpunit": "^10.5.53", - "squizlabs/php_codesniffer": "^3.13.4" - }, - "bin": [ - "bin/carbon" - ], - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Carbon\\Laravel\\ServiceProvider" - ] - }, - "phpstan": { - "includes": [ - "extension.neon" - ] - }, - "branch-alias": { - "dev-2.x": "2.x-dev", - "dev-master": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Carbon\\": "src/Carbon/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Brian Nesbitt", - "email": "brian@nesbot.com", - "homepage": "https://markido.com" - }, - { - "name": "kylekatarnls", - "homepage": "https://github.com/kylekatarnls" - } - ], - "description": "An API extension for DateTime that supports 281 different languages.", - "homepage": "https://carbon.nesbot.com", - "keywords": [ - "date", - "datetime", - "time" - ], - "support": { - "docs": "https://carbon.nesbot.com/docs", - "issues": "https://github.com/CarbonPHP/carbon/issues", - "source": "https://github.com/CarbonPHP/carbon" - }, - "funding": [ - { - "url": "https://github.com/sponsors/kylekatarnls", - "type": "github" - }, - { - "url": "https://opencollective.com/Carbon#sponsor", - "type": "opencollective" - }, - { - "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", - "type": "tidelift" - } - ], - "time": "2025-09-06T13:39:36+00:00" - }, - { - "name": "nette/schema", - "version": "v1.3.2", - "source": { - "type": "git", - "url": "https://github.com/nette/schema.git", - "reference": "da801d52f0354f70a638673c4a0f04e16529431d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/schema/zipball/da801d52f0354f70a638673c4a0f04e16529431d", - "reference": "da801d52f0354f70a638673c4a0f04e16529431d", - "shasum": "" - }, - "require": { - "nette/utils": "^4.0", - "php": "8.1 - 8.4" - }, - "require-dev": { - "nette/tester": "^2.5.2", - "phpstan/phpstan-nette": "^1.0", - "tracy/tracy": "^2.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0-only", - "GPL-3.0-only" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "📐 Nette Schema: validating data structures against a given Schema.", - "homepage": "https://nette.org", - "keywords": [ - "config", - "nette" - ], - "support": { - "issues": "https://github.com/nette/schema/issues", - "source": "https://github.com/nette/schema/tree/v1.3.2" - }, - "time": "2024-10-06T23:10:23+00:00" - }, - { - "name": "nette/utils", - "version": "v4.0.8", - "source": { - "type": "git", - "url": "https://github.com/nette/utils.git", - "reference": "c930ca4e3cf4f17dcfb03037703679d2396d2ede" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/c930ca4e3cf4f17dcfb03037703679d2396d2ede", - "reference": "c930ca4e3cf4f17dcfb03037703679d2396d2ede", - "shasum": "" - }, - "require": { - "php": "8.0 - 8.5" - }, - "conflict": { - "nette/finder": "<3", - "nette/schema": "<1.2.2" - }, - "require-dev": { - "jetbrains/phpstorm-attributes": "^1.2", - "nette/tester": "^2.5", - "phpstan/phpstan-nette": "^2.0@stable", - "tracy/tracy": "^2.9" - }, - "suggest": { - "ext-gd": "to use Image", - "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", - "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", - "ext-json": "to use Nette\\Utils\\Json", - "ext-mbstring": "to use Strings::lower() etc...", - "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "psr-4": { - "Nette\\": "src" - }, - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0-only", - "GPL-3.0-only" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", - "homepage": "https://nette.org", - "keywords": [ - "array", - "core", - "datetime", - "images", - "json", - "nette", - "paginator", - "password", - "slugify", - "string", - "unicode", - "utf-8", - "utility", - "validation" - ], - "support": { - "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.0.8" - }, - "time": "2025-08-06T21:43:34+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v5.6.1", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", - "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-json": "*", - "ext-tokenizer": "*", - "php": ">=7.4" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.1" - }, - "time": "2025-08-13T20:13:15+00:00" - }, - { - "name": "nunomaduro/termwind", - "version": "v2.3.1", - "source": { - "type": "git", - "url": "https://github.com/nunomaduro/termwind.git", - "reference": "dfa08f390e509967a15c22493dc0bac5733d9123" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/dfa08f390e509967a15c22493dc0bac5733d9123", - "reference": "dfa08f390e509967a15c22493dc0bac5733d9123", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": "^8.2", - "symfony/console": "^7.2.6" - }, - "require-dev": { - "illuminate/console": "^11.44.7", - "laravel/pint": "^1.22.0", - "mockery/mockery": "^1.6.12", - "pestphp/pest": "^2.36.0 || ^3.8.2", - "phpstan/phpstan": "^1.12.25", - "phpstan/phpstan-strict-rules": "^1.6.2", - "symfony/var-dumper": "^7.2.6", - "thecodingmachine/phpstan-strict-rules": "^1.0.0" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Termwind\\Laravel\\TermwindServiceProvider" - ] - }, - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "files": [ - "src/Functions.php" - ], - "psr-4": { - "Termwind\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "Its like Tailwind CSS, but for the console.", - "keywords": [ - "cli", - "console", - "css", - "package", - "php", - "style" - ], - "support": { - "issues": "https://github.com/nunomaduro/termwind/issues", - "source": "https://github.com/nunomaduro/termwind/tree/v2.3.1" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - }, - { - "url": "https://github.com/xiCO2k", - "type": "github" - } - ], - "time": "2025-05-08T08:14:37+00:00" - }, - { - "name": "phpoption/phpoption", - "version": "1.9.4", - "source": { - "type": "git", - "url": "https://github.com/schmittjoh/php-option.git", - "reference": "638a154f8d4ee6a5cfa96d6a34dfbe0cffa9566d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/638a154f8d4ee6a5cfa96d6a34dfbe0cffa9566d", - "reference": "638a154f8d4ee6a5cfa96d6a34dfbe0cffa9566d", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.44 || ^9.6.25 || ^10.5.53 || ^11.5.34" - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - }, - "branch-alias": { - "dev-master": "1.9-dev" - } - }, - "autoload": { - "psr-4": { - "PhpOption\\": "src/PhpOption/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "https://github.com/schmittjoh" - }, - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - } - ], - "description": "Option Type for PHP", - "keywords": [ - "language", - "option", - "php", - "type" - ], - "support": { - "issues": "https://github.com/schmittjoh/php-option/issues", - "source": "https://github.com/schmittjoh/php-option/tree/1.9.4" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", - "type": "tidelift" - } - ], - "time": "2025-08-21T11:53:16+00:00" - }, - { - "name": "psr/clock", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/clock.git", - "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", - "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Psr\\Clock\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for reading the clock.", - "homepage": "https://github.com/php-fig/clock", - "keywords": [ - "clock", - "now", - "psr", - "psr-20", - "time" - ], - "support": { - "issues": "https://github.com/php-fig/clock/issues", - "source": "https://github.com/php-fig/clock/tree/1.0.0" - }, - "time": "2022-11-25T14:36:26+00:00" - }, - { - "name": "psr/container", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "shasum": "" - }, - "require": { - "php": ">=7.4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Container\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" - ], - "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/2.0.2" - }, - "time": "2021-11-05T16:47:00+00:00" - }, - { - "name": "psr/event-dispatcher", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/event-dispatcher.git", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", - "shasum": "" - }, - "require": { - "php": ">=7.2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\EventDispatcher\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Standard interfaces for event handling.", - "keywords": [ - "events", - "psr", - "psr-14" - ], - "support": { - "issues": "https://github.com/php-fig/event-dispatcher/issues", - "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" - }, - "time": "2019-01-08T18:20:26+00:00" - }, - { - "name": "psr/http-client", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", - "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0", - "psr/http-message": "^1.0 || ^2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Client\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP clients", - "homepage": "https://github.com/php-fig/http-client", - "keywords": [ - "http", - "http-client", - "psr", - "psr-18" - ], - "support": { - "source": "https://github.com/php-fig/http-client" - }, - "time": "2023-09-23T14:17:50+00:00" - }, - { - "name": "psr/http-factory", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", - "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", - "shasum": "" - }, - "require": { - "php": ">=7.1", - "psr/http-message": "^1.0 || ^2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", - "keywords": [ - "factory", - "http", - "message", - "psr", - "psr-17", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-factory" - }, - "time": "2024-04-15T12:06:14+00:00" - }, - { - "name": "psr/http-message", - "version": "2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-message/tree/2.0" - }, - "time": "2023-04-04T09:54:51+00:00" - }, - { - "name": "psr/log", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "support": { - "source": "https://github.com/php-fig/log/tree/3.0.2" - }, - "time": "2024-09-11T13:17:53+00:00" - }, - { - "name": "psr/simple-cache", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/simple-cache.git", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\SimpleCache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interfaces for simple caching", - "keywords": [ - "cache", - "caching", - "psr", - "psr-16", - "simple-cache" - ], - "support": { - "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" - }, - "time": "2021-10-29T13:26:27+00:00" - }, - { - "name": "psy/psysh", - "version": "v0.12.12", - "source": { - "type": "git", - "url": "https://github.com/bobthecow/psysh.git", - "reference": "cd23863404a40ccfaf733e3af4db2b459837f7e7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/cd23863404a40ccfaf733e3af4db2b459837f7e7", - "reference": "cd23863404a40ccfaf733e3af4db2b459837f7e7", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-tokenizer": "*", - "nikic/php-parser": "^5.0 || ^4.0", - "php": "^8.0 || ^7.4", - "symfony/console": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4", - "symfony/var-dumper": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4" - }, - "conflict": { - "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.2" - }, - "suggest": { - "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", - "ext-pdo-sqlite": "The doc command requires SQLite to work.", - "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well." - }, - "bin": [ - "bin/psysh" - ], - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": false, - "forward-command": false - }, - "branch-alias": { - "dev-main": "0.12.x-dev" - } - }, - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "Psy\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Justin Hileman", - "email": "justin@justinhileman.info" - } - ], - "description": "An interactive shell for modern PHP.", - "homepage": "https://psysh.org", - "keywords": [ - "REPL", - "console", - "interactive", - "shell" - ], - "support": { - "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.12.12" - }, - "time": "2025-09-20T13:46:31+00:00" - }, - { - "name": "ralouphie/getallheaders", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/ralouphie/getallheaders.git", - "reference": "120b605dfeb996808c31b6477290a714d356e822" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", - "reference": "120b605dfeb996808c31b6477290a714d356e822", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "^5 || ^6.5" - }, - "type": "library", - "autoload": { - "files": [ - "src/getallheaders.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ralph Khattar", - "email": "ralph.khattar@gmail.com" - } - ], - "description": "A polyfill for getallheaders.", - "support": { - "issues": "https://github.com/ralouphie/getallheaders/issues", - "source": "https://github.com/ralouphie/getallheaders/tree/develop" - }, - "time": "2019-03-08T08:55:37+00:00" - }, - { - "name": "ramsey/collection", - "version": "2.1.1", - "source": { - "type": "git", - "url": "https://github.com/ramsey/collection.git", - "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/344572933ad0181accbf4ba763e85a0306a8c5e2", - "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2", - "shasum": "" - }, - "require": { - "php": "^8.1" - }, - "require-dev": { - "captainhook/plugin-composer": "^5.3", - "ergebnis/composer-normalize": "^2.45", - "fakerphp/faker": "^1.24", - "hamcrest/hamcrest-php": "^2.0", - "jangregor/phpstan-prophecy": "^2.1", - "mockery/mockery": "^1.6", - "php-parallel-lint/php-console-highlighter": "^1.0", - "php-parallel-lint/php-parallel-lint": "^1.4", - "phpspec/prophecy-phpunit": "^2.3", - "phpstan/extension-installer": "^1.4", - "phpstan/phpstan": "^2.1", - "phpstan/phpstan-mockery": "^2.0", - "phpstan/phpstan-phpunit": "^2.0", - "phpunit/phpunit": "^10.5", - "ramsey/coding-standard": "^2.3", - "ramsey/conventional-commits": "^1.6", - "roave/security-advisories": "dev-latest" - }, - "type": "library", - "extra": { - "captainhook": { - "force-install": true - }, - "ramsey/conventional-commits": { - "configFile": "conventional-commits.json" - } - }, - "autoload": { - "psr-4": { - "Ramsey\\Collection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ben Ramsey", - "email": "ben@benramsey.com", - "homepage": "https://benramsey.com" - } - ], - "description": "A PHP library for representing and manipulating collections.", - "keywords": [ - "array", - "collection", - "hash", - "map", - "queue", - "set" - ], - "support": { - "issues": "https://github.com/ramsey/collection/issues", - "source": "https://github.com/ramsey/collection/tree/2.1.1" - }, - "time": "2025-03-22T05:38:12+00:00" - }, - { - "name": "ramsey/uuid", - "version": "4.9.1", - "source": { - "type": "git", - "url": "https://github.com/ramsey/uuid.git", - "reference": "81f941f6f729b1e3ceea61d9d014f8b6c6800440" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/81f941f6f729b1e3ceea61d9d014f8b6c6800440", - "reference": "81f941f6f729b1e3ceea61d9d014f8b6c6800440", - "shasum": "" - }, - "require": { - "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14", - "php": "^8.0", - "ramsey/collection": "^1.2 || ^2.0" - }, - "replace": { - "rhumsaa/uuid": "self.version" - }, - "require-dev": { - "captainhook/captainhook": "^5.25", - "captainhook/plugin-composer": "^5.3", - "dealerdirect/phpcodesniffer-composer-installer": "^1.0", - "ergebnis/composer-normalize": "^2.47", - "mockery/mockery": "^1.6", - "paragonie/random-lib": "^2", - "php-mock/php-mock": "^2.6", - "php-mock/php-mock-mockery": "^1.5", - "php-parallel-lint/php-parallel-lint": "^1.4.0", - "phpbench/phpbench": "^1.2.14", - "phpstan/extension-installer": "^1.4", - "phpstan/phpstan": "^2.1", - "phpstan/phpstan-mockery": "^2.0", - "phpstan/phpstan-phpunit": "^2.0", - "phpunit/phpunit": "^9.6", - "slevomat/coding-standard": "^8.18", - "squizlabs/php_codesniffer": "^3.13" - }, - "suggest": { - "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", - "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", - "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", - "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", - "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." - }, - "type": "library", - "extra": { - "captainhook": { - "force-install": true - } - }, - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "Ramsey\\Uuid\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", - "keywords": [ - "guid", - "identifier", - "uuid" - ], - "support": { - "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.9.1" - }, - "time": "2025-09-04T20:59:21+00:00" - }, - { - "name": "spatie/laravel-permission", - "version": "6.21.0", - "source": { - "type": "git", - "url": "https://github.com/spatie/laravel-permission.git", - "reference": "6a118e8855dfffcd90403aab77bbf35a03db51b3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/6a118e8855dfffcd90403aab77bbf35a03db51b3", - "reference": "6a118e8855dfffcd90403aab77bbf35a03db51b3", - "shasum": "" - }, - "require": { - "illuminate/auth": "^8.12|^9.0|^10.0|^11.0|^12.0", - "illuminate/container": "^8.12|^9.0|^10.0|^11.0|^12.0", - "illuminate/contracts": "^8.12|^9.0|^10.0|^11.0|^12.0", - "illuminate/database": "^8.12|^9.0|^10.0|^11.0|^12.0", - "php": "^8.0" - }, - "require-dev": { - "laravel/passport": "^11.0|^12.0", - "laravel/pint": "^1.0", - "orchestra/testbench": "^6.23|^7.0|^8.0|^9.0|^10.0", - "phpunit/phpunit": "^9.4|^10.1|^11.5" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Spatie\\Permission\\PermissionServiceProvider" - ] - }, - "branch-alias": { - "dev-main": "6.x-dev", - "dev-master": "6.x-dev" - } - }, - "autoload": { - "files": [ - "src/helpers.php" - ], - "psr-4": { - "Spatie\\Permission\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://spatie.be", - "role": "Developer" - } - ], - "description": "Permission handling for Laravel 8.0 and up", - "homepage": "https://github.com/spatie/laravel-permission", - "keywords": [ - "acl", - "laravel", - "permission", - "permissions", - "rbac", - "roles", - "security", - "spatie" - ], - "support": { - "issues": "https://github.com/spatie/laravel-permission/issues", - "source": "https://github.com/spatie/laravel-permission/tree/6.21.0" - }, - "funding": [ - { - "url": "https://github.com/spatie", - "type": "github" - } - ], - "time": "2025-07-23T16:08:05+00:00" - }, - { - "name": "symfony/clock", - "version": "v7.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/clock.git", - "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/clock/zipball/b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", - "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "psr/clock": "^1.0", - "symfony/polyfill-php83": "^1.28" - }, - "provide": { - "psr/clock-implementation": "1.0" - }, - "type": "library", - "autoload": { - "files": [ - "Resources/now.php" - ], - "psr-4": { - "Symfony\\Component\\Clock\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "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": "Decouples applications from the system clock", - "homepage": "https://symfony.com", - "keywords": [ - "clock", - "psr20", - "time" - ], - "support": { - "source": "https://github.com/symfony/clock/tree/v7.3.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-25T14:21:43+00:00" - }, - { - "name": "symfony/console", - "version": "v7.3.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "2b9c5fafbac0399a20a2e82429e2bd735dcfb7db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/2b9c5fafbac0399a20a2e82429e2bd735dcfb7db", - "reference": "2b9c5fafbac0399a20a2e82429e2bd735dcfb7db", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^7.2" - }, - "conflict": { - "symfony/dependency-injection": "<6.4", - "symfony/dotenv": "<6.4", - "symfony/event-dispatcher": "<6.4", - "symfony/lock": "<6.4", - "symfony/process": "<6.4" - }, - "provide": { - "psr/log-implementation": "1.0|2.0|3.0" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/stopwatch": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Eases the creation of beautiful and testable command line interfaces", - "homepage": "https://symfony.com", - "keywords": [ - "cli", - "command-line", - "console", - "terminal" - ], - "support": { - "source": "https://github.com/symfony/console/tree/v7.3.4" - }, - "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": "2025-09-22T15:31:00+00:00" - }, - { - "name": "symfony/css-selector", - "version": "v7.3.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/css-selector.git", - "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/601a5ce9aaad7bf10797e3663faefce9e26c24e2", - "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\CssSelector\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Jean-François Simon", - "email": "jeanfrancois.simon@sensiolabs.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Converts CSS selectors to XPath expressions", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/css-selector/tree/v7.3.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-25T14:21:43+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v3.6.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", - "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/contracts", - "name": "symfony/contracts" - }, - "branch-alias": { - "dev-main": "3.6-dev" - } - }, - "autoload": { - "files": [ - "function.php" - ] - }, - "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": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-25T14:21:43+00:00" - }, - { - "name": "symfony/error-handler", - "version": "v7.3.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/error-handler.git", - "reference": "99f81bc944ab8e5dae4f21b4ca9972698bbad0e4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/99f81bc944ab8e5dae4f21b4ca9972698bbad0e4", - "reference": "99f81bc944ab8e5dae4f21b4ca9972698bbad0e4", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "psr/log": "^1|^2|^3", - "symfony/var-dumper": "^6.4|^7.0" - }, - "conflict": { - "symfony/deprecation-contracts": "<2.5", - "symfony/http-kernel": "<6.4" - }, - "require-dev": { - "symfony/console": "^6.4|^7.0", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/serializer": "^6.4|^7.0", - "symfony/webpack-encore-bundle": "^1.0|^2.0" - }, - "bin": [ - "Resources/bin/patch-type-declarations" - ], - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\ErrorHandler\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides tools to manage errors and ease debugging PHP code", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/error-handler/tree/v7.3.4" - }, - "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": "2025-09-11T10:12:26+00:00" - }, - { - "name": "symfony/event-dispatcher", - "version": "v7.3.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b7dc69e71de420ac04bc9ab830cf3ffebba48191", - "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/event-dispatcher-contracts": "^2.5|^3" - }, - "conflict": { - "symfony/dependency-injection": "<6.4", - "symfony/service-contracts": "<2.5" - }, - "provide": { - "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "2.0|3.0" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/error-handler": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "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/v7.3.3" - }, - "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": "2025-08-13T11:49:31+00:00" - }, - { - "name": "symfony/event-dispatcher-contracts", - "version": "v3.6.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "59eb412e93815df44f05f342958efa9f46b1e586" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/59eb412e93815df44f05f342958efa9f46b1e586", - "reference": "59eb412e93815df44f05f342958efa9f46b1e586", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "psr/event-dispatcher": "^1" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/contracts", - "name": "symfony/contracts" - }, - "branch-alias": { - "dev-main": "3.6-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\EventDispatcher\\": "" - } - }, - "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": "Generic abstractions related to dispatching event", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.6.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-25T14:21:43+00:00" - }, - { - "name": "symfony/finder", - "version": "v7.3.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "2a6614966ba1074fa93dae0bc804227422df4dfe" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/2a6614966ba1074fa93dae0bc804227422df4dfe", - "reference": "2a6614966ba1074fa93dae0bc804227422df4dfe", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "symfony/filesystem": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Finds files and directories via an intuitive fluent interface", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/finder/tree/v7.3.2" - }, - "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": "2025-07-15T13:41:35+00:00" - }, - { - "name": "symfony/http-foundation", - "version": "v7.3.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-foundation.git", - "reference": "c061c7c18918b1b64268771aad04b40be41dd2e6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/c061c7c18918b1b64268771aad04b40be41dd2e6", - "reference": "c061c7c18918b1b64268771aad04b40be41dd2e6", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3.0", - "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php83": "^1.27" - }, - "conflict": { - "doctrine/dbal": "<3.6", - "symfony/cache": "<6.4.12|>=7.0,<7.1.5" - }, - "require-dev": { - "doctrine/dbal": "^3.6|^4", - "predis/predis": "^1.1|^2.0", - "symfony/cache": "^6.4.12|^7.1.5", - "symfony/clock": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/mime": "^6.4|^7.0", - "symfony/rate-limiter": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpFoundation\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Defines an object-oriented layer for the HTTP specification", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.3.4" - }, - "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": "2025-09-16T08:38:17+00:00" - }, - { - "name": "symfony/http-kernel", - "version": "v7.3.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-kernel.git", - "reference": "b796dffea7821f035047235e076b60ca2446e3cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/b796dffea7821f035047235e076b60ca2446e3cf", - "reference": "b796dffea7821f035047235e076b60ca2446e3cf", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/error-handler": "^6.4|^7.0", - "symfony/event-dispatcher": "^7.3", - "symfony/http-foundation": "^7.3", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "symfony/browser-kit": "<6.4", - "symfony/cache": "<6.4", - "symfony/config": "<6.4", - "symfony/console": "<6.4", - "symfony/dependency-injection": "<6.4", - "symfony/doctrine-bridge": "<6.4", - "symfony/form": "<6.4", - "symfony/http-client": "<6.4", - "symfony/http-client-contracts": "<2.5", - "symfony/mailer": "<6.4", - "symfony/messenger": "<6.4", - "symfony/translation": "<6.4", - "symfony/translation-contracts": "<2.5", - "symfony/twig-bridge": "<6.4", - "symfony/validator": "<6.4", - "symfony/var-dumper": "<6.4", - "twig/twig": "<3.12" - }, - "provide": { - "psr/log-implementation": "1.0|2.0|3.0" - }, - "require-dev": { - "psr/cache": "^1.0|^2.0|^3.0", - "symfony/browser-kit": "^6.4|^7.0", - "symfony/clock": "^6.4|^7.0", - "symfony/config": "^6.4|^7.0", - "symfony/console": "^6.4|^7.0", - "symfony/css-selector": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/dom-crawler": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/finder": "^6.4|^7.0", - "symfony/http-client-contracts": "^2.5|^3", - "symfony/process": "^6.4|^7.0", - "symfony/property-access": "^7.1", - "symfony/routing": "^6.4|^7.0", - "symfony/serializer": "^7.1", - "symfony/stopwatch": "^6.4|^7.0", - "symfony/translation": "^6.4|^7.0", - "symfony/translation-contracts": "^2.5|^3", - "symfony/uid": "^6.4|^7.0", - "symfony/validator": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0", - "symfony/var-exporter": "^6.4|^7.0", - "twig/twig": "^3.12" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpKernel\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "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/v7.3.4" - }, - "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": "2025-09-27T12:32:17+00:00" - }, - { - "name": "symfony/mailer", - "version": "v7.3.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/mailer.git", - "reference": "ab97ef2f7acf0216955f5845484235113047a31d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/ab97ef2f7acf0216955f5845484235113047a31d", - "reference": "ab97ef2f7acf0216955f5845484235113047a31d", - "shasum": "" - }, - "require": { - "egulias/email-validator": "^2.1.10|^3|^4", - "php": ">=8.2", - "psr/event-dispatcher": "^1", - "psr/log": "^1|^2|^3", - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/mime": "^7.2", - "symfony/service-contracts": "^2.5|^3" - }, - "conflict": { - "symfony/http-client-contracts": "<2.5", - "symfony/http-kernel": "<6.4", - "symfony/messenger": "<6.4", - "symfony/mime": "<6.4", - "symfony/twig-bridge": "<6.4" - }, - "require-dev": { - "symfony/console": "^6.4|^7.0", - "symfony/http-client": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/twig-bridge": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Mailer\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Helps sending emails", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/mailer/tree/v7.3.4" - }, - "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": "2025-09-17T05:51:54+00:00" - }, - { - "name": "symfony/mime", - "version": "v7.3.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/mime.git", - "reference": "b1b828f69cbaf887fa835a091869e55df91d0e35" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/b1b828f69cbaf887fa835a091869e55df91d0e35", - "reference": "b1b828f69cbaf887fa835a091869e55df91d0e35", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/polyfill-intl-idn": "^1.10", - "symfony/polyfill-mbstring": "^1.0" - }, - "conflict": { - "egulias/email-validator": "~3.0.0", - "phpdocumentor/reflection-docblock": "<3.2.2", - "phpdocumentor/type-resolver": "<1.4.0", - "symfony/mailer": "<6.4", - "symfony/serializer": "<6.4.3|>7.0,<7.0.3" - }, - "require-dev": { - "egulias/email-validator": "^2.1.10|^3.1|^4", - "league/html-to-markdown": "^5.0", - "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/property-access": "^6.4|^7.0", - "symfony/property-info": "^6.4|^7.0", - "symfony/serializer": "^6.4.3|^7.0.3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Mime\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Allows manipulating MIME messages", - "homepage": "https://symfony.com", - "keywords": [ - "mime", - "mime-type" - ], - "support": { - "source": "https://github.com/symfony/mime/tree/v7.3.4" - }, - "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": "2025-09-16T08:38:17+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.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": "2024-09-09T11:45:10+00:00" - }, - { - "name": "symfony/polyfill-intl-grapheme", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", - "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - } - }, - "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 for intl's grapheme_* functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "grapheme", - "intl", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.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": "2025-06-27T09:58:17+00:00" - }, - { - "name": "symfony/polyfill-intl-idn", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", - "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", - "shasum": "" - }, - "require": { - "php": ">=7.2", - "symfony/polyfill-intl-normalizer": "^1.10" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Idn\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Laurent Bassin", - "email": "laurent@bassin.info" - }, - { - "name": "Trevor Rowbotham", - "email": "trevor.rowbotham@pm.me" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "idn", - "intl", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.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": "2024-09-10T14:38:51+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "3833d7255cc303546435cb650316bff708a1c75c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", - "reference": "3833d7255cc303546435cb650316bff708a1c75c", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, - "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 for intl's Normalizer class and related functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "intl", - "normalizer", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.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": "2024-09-09T11:45:10+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", - "shasum": "" - }, - "require": { - "ext-iconv": "*", - "php": ">=7.2" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "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 for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.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": "2024-12-23T08:48:59+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", - "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", - "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\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.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": "2025-01-02T08:10:11+00:00" - }, - { - "name": "symfony/polyfill-php83", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/17f6f9a6b1735c0f163024d959f700cfbc5155e5", - "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5", - "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.33.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": "2025-07-08T02:45:35+00:00" - }, - { - "name": "symfony/polyfill-php84", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php84.git", - "reference": "d8ced4d875142b6a7426000426b8abc631d6b191" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191", - "reference": "d8ced4d875142b6a7426000426b8abc631d6b191", - "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\\Php84\\": "" - }, - "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.4+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.33.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": "2025-06-24T13:30:11+00:00" - }, - { - "name": "symfony/polyfill-php85", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php85.git", - "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91", - "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91", - "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\\Php85\\": "" - }, - "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.5+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php85/tree/v1.33.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": "2025-06-23T16:12:55+00:00" - }, - { - "name": "symfony/polyfill-uuid", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-uuid.git", - "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/21533be36c24be3f4b1669c4725c7d1d2bab4ae2", - "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "provide": { - "ext-uuid": "*" - }, - "suggest": { - "ext-uuid": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Uuid\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Grégoire Pineau", - "email": "lyrixx@lyrixx.info" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for uuid functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "uuid" - ], - "support": { - "source": "https://github.com/symfony/polyfill-uuid/tree/v1.33.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": "2024-09-09T11:45:10+00:00" - }, - { - "name": "symfony/process", - "version": "v7.3.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/f24f8f316367b30810810d4eb30c543d7003ff3b", - "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Process\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Executes commands in sub-processes", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/process/tree/v7.3.4" - }, - "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": "2025-09-11T10:12:26+00:00" - }, - { - "name": "symfony/routing", - "version": "v7.3.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/routing.git", - "reference": "8dc648e159e9bac02b703b9fbd937f19ba13d07c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/8dc648e159e9bac02b703b9fbd937f19ba13d07c", - "reference": "8dc648e159e9bac02b703b9fbd937f19ba13d07c", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3" - }, - "conflict": { - "symfony/config": "<6.4", - "symfony/dependency-injection": "<6.4", - "symfony/yaml": "<6.4" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/yaml": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Routing\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Maps an HTTP request to a set of configuration variables", - "homepage": "https://symfony.com", - "keywords": [ - "router", - "routing", - "uri", - "url" - ], - "support": { - "source": "https://github.com/symfony/routing/tree/v7.3.4" - }, - "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": "2025-09-11T10:12:26+00:00" - }, - { - "name": "symfony/service-contracts", - "version": "v3.6.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4", - "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "psr/container": "^1.1|^2.0", - "symfony/deprecation-contracts": "^2.5|^3" - }, - "conflict": { - "ext-psr": "<1.1|>=2" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/contracts", - "name": "symfony/contracts" - }, - "branch-alias": { - "dev-main": "3.6-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Service\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] - }, - "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": "Generic abstractions related to writing services", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.6.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2025-04-25T09:37:31+00:00" - }, - { - "name": "symfony/string", - "version": "v7.3.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/string.git", - "reference": "f96476035142921000338bad71e5247fbc138872" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/f96476035142921000338bad71e5247fbc138872", - "reference": "f96476035142921000338bad71e5247fbc138872", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-intl-grapheme": "~1.0", - "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/translation-contracts": "<2.5" - }, - "require-dev": { - "symfony/emoji": "^7.1", - "symfony/http-client": "^6.4|^7.0", - "symfony/intl": "^6.4|^7.0", - "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "files": [ - "Resources/functions.php" - ], - "psr-4": { - "Symfony\\Component\\String\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "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": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", - "homepage": "https://symfony.com", - "keywords": [ - "grapheme", - "i18n", - "string", - "unicode", - "utf-8", - "utf8" - ], - "support": { - "source": "https://github.com/symfony/string/tree/v7.3.4" - }, - "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": "2025-09-11T14:36:48+00:00" - }, - { - "name": "symfony/translation", - "version": "v7.3.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/translation.git", - "reference": "ec25870502d0c7072d086e8ffba1420c85965174" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/ec25870502d0c7072d086e8ffba1420c85965174", - "reference": "ec25870502d0c7072d086e8ffba1420c85965174", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/translation-contracts": "^2.5|^3.0" - }, - "conflict": { - "nikic/php-parser": "<5.0", - "symfony/config": "<6.4", - "symfony/console": "<6.4", - "symfony/dependency-injection": "<6.4", - "symfony/http-client-contracts": "<2.5", - "symfony/http-kernel": "<6.4", - "symfony/service-contracts": "<2.5", - "symfony/twig-bundle": "<6.4", - "symfony/yaml": "<6.4" - }, - "provide": { - "symfony/translation-implementation": "2.3|3.0" - }, - "require-dev": { - "nikic/php-parser": "^5.0", - "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/console": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/finder": "^6.4|^7.0", - "symfony/http-client-contracts": "^2.5|^3.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/intl": "^6.4|^7.0", - "symfony/polyfill-intl-icu": "^1.21", - "symfony/routing": "^6.4|^7.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/yaml": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "files": [ - "Resources/functions.php" - ], - "psr-4": { - "Symfony\\Component\\Translation\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides tools to internationalize your application", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/translation/tree/v7.3.4" - }, - "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": "2025-09-07T11:39:36+00:00" - }, - { - "name": "symfony/translation-contracts", - "version": "v3.6.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/translation-contracts.git", - "reference": "df210c7a2573f1913b2d17cc95f90f53a73d8f7d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/df210c7a2573f1913b2d17cc95f90f53a73d8f7d", - "reference": "df210c7a2573f1913b2d17cc95f90f53a73d8f7d", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/contracts", - "name": "symfony/contracts" - }, - "branch-alias": { - "dev-main": "3.6-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Translation\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] - }, - "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": "Generic abstractions related to translation", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.6.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-27T08:32:26+00:00" - }, - { - "name": "symfony/uid", - "version": "v7.3.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/uid.git", - "reference": "a69f69f3159b852651a6bf45a9fdd149520525bb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/a69f69f3159b852651a6bf45a9fdd149520525bb", - "reference": "a69f69f3159b852651a6bf45a9fdd149520525bb", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/polyfill-uuid": "^1.15" - }, - "require-dev": { - "symfony/console": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Uid\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Grégoire Pineau", - "email": "lyrixx@lyrixx.info" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides an object-oriented API to generate and represent UIDs", - "homepage": "https://symfony.com", - "keywords": [ - "UID", - "ulid", - "uuid" - ], - "support": { - "source": "https://github.com/symfony/uid/tree/v7.3.1" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2025-06-27T19:55:54+00:00" - }, - { - "name": "symfony/var-dumper", - "version": "v7.3.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/var-dumper.git", - "reference": "b8abe7daf2730d07dfd4b2ee1cecbf0dd2fbdabb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/b8abe7daf2730d07dfd4b2ee1cecbf0dd2fbdabb", - "reference": "b8abe7daf2730d07dfd4b2ee1cecbf0dd2fbdabb", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/console": "<6.4" - }, - "require-dev": { - "symfony/console": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/uid": "^6.4|^7.0", - "twig/twig": "^3.12" - }, - "bin": [ - "Resources/bin/var-dump-server" - ], - "type": "library", - "autoload": { - "files": [ - "Resources/functions/dump.php" - ], - "psr-4": { - "Symfony\\Component\\VarDumper\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "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": "Provides mechanisms for walking through any arbitrary PHP variable", - "homepage": "https://symfony.com", - "keywords": [ - "debug", - "dump" - ], - "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.3.4" - }, - "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": "2025-09-11T10:12:26+00:00" - }, - { - "name": "tijsverkoyen/css-to-inline-styles", - "version": "v2.3.0", - "source": { - "type": "git", - "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", - "reference": "0d72ac1c00084279c1816675284073c5a337c20d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/0d72ac1c00084279c1816675284073c5a337c20d", - "reference": "0d72ac1c00084279c1816675284073c5a337c20d", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "php": "^7.4 || ^8.0", - "symfony/css-selector": "^5.4 || ^6.0 || ^7.0" - }, - "require-dev": { - "phpstan/phpstan": "^2.0", - "phpstan/phpstan-phpunit": "^2.0", - "phpunit/phpunit": "^8.5.21 || ^9.5.10" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "TijsVerkoyen\\CssToInlineStyles\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Tijs Verkoyen", - "email": "css_to_inline_styles@verkoyen.eu", - "role": "Developer" - } - ], - "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", - "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", - "support": { - "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", - "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.3.0" - }, - "time": "2024-12-21T16:25:41+00:00" - }, - { - "name": "tymon/jwt-auth", - "version": "2.2.1", - "source": { - "type": "git", - "url": "https://github.com/tymondesigns/jwt-auth.git", - "reference": "42381e56db1bf887c12e5302d11901d65cc74856" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/tymondesigns/jwt-auth/zipball/42381e56db1bf887c12e5302d11901d65cc74856", - "reference": "42381e56db1bf887c12e5302d11901d65cc74856", - "shasum": "" - }, - "require": { - "illuminate/auth": "^9.0|^10.0|^11.0|^12.0", - "illuminate/contracts": "^9.0|^10.0|^11.0|^12.0", - "illuminate/http": "^9.0|^10.0|^11.0|^12.0", - "illuminate/support": "^9.0|^10.0|^11.0|^12.0", - "lcobucci/jwt": "^4.0", - "nesbot/carbon": "^2.69|^3.0", - "php": "^8.0" - }, - "require-dev": { - "illuminate/console": "^9.0|^10.0|^11.0|^12.0", - "illuminate/database": "^9.0|^10.0|^11.0|^12.0", - "illuminate/routing": "^9.0|^10.0|^11.0|^12.0", - "mockery/mockery": "^1.6", - "phpunit/phpunit": "^9.4" - }, - "type": "library", - "extra": { - "laravel": { - "aliases": { - "JWTAuth": "Tymon\\JWTAuth\\Facades\\JWTAuth", - "JWTFactory": "Tymon\\JWTAuth\\Facades\\JWTFactory" - }, - "providers": [ - "Tymon\\JWTAuth\\Providers\\LaravelServiceProvider" - ] - }, - "branch-alias": { - "dev-2.x": "2.0-dev", - "dev-develop": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "Tymon\\JWTAuth\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Sean Tymon", - "email": "tymon148@gmail.com", - "homepage": "https://tymon.xyz", - "role": "Developer" - } - ], - "description": "JSON Web Token Authentication for Laravel and Lumen", - "homepage": "https://github.com/tymondesigns/jwt-auth", - "keywords": [ - "Authentication", - "JSON Web Token", - "auth", - "jwt", - "laravel" - ], - "support": { - "issues": "https://github.com/tymondesigns/jwt-auth/issues", - "source": "https://github.com/tymondesigns/jwt-auth" - }, - "funding": [ - { - "url": "https://www.patreon.com/seantymon", - "type": "patreon" - } - ], - "time": "2025-04-16T22:22:54+00:00" - }, - { - "name": "vlucas/phpdotenv", - "version": "v5.6.2", - "source": { - "type": "git", - "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/24ac4c74f91ee2c193fa1aaa5c249cb0822809af", - "reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "graham-campbell/result-type": "^1.1.3", - "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.3", - "symfony/polyfill-ctype": "^1.24", - "symfony/polyfill-mbstring": "^1.24", - "symfony/polyfill-php80": "^1.24" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "ext-filter": "*", - "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" - }, - "suggest": { - "ext-filter": "Required to use the boolean validator." - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - }, - "branch-alias": { - "dev-master": "5.6-dev" - } - }, - "autoload": { - "psr-4": { - "Dotenv\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Vance Lucas", - "email": "vance@vancelucas.com", - "homepage": "https://github.com/vlucas" - } - ], - "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", - "keywords": [ - "dotenv", - "env", - "environment" - ], - "support": { - "issues": "https://github.com/vlucas/phpdotenv/issues", - "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.2" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", - "type": "tidelift" - } - ], - "time": "2025-04-30T23:37:27+00:00" - }, - { - "name": "voku/portable-ascii", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/voku/portable-ascii.git", - "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", - "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", - "shasum": "" - }, - "require": { - "php": ">=7.0.0" - }, - "require-dev": { - "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" - }, - "suggest": { - "ext-intl": "Use Intl for transliterator_transliterate() support" - }, - "type": "library", - "autoload": { - "psr-4": { - "voku\\": "src/voku/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Lars Moelleken", - "homepage": "https://www.moelleken.org/" - } - ], - "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", - "homepage": "https://github.com/voku/portable-ascii", - "keywords": [ - "ascii", - "clean", - "php" - ], - "support": { - "issues": "https://github.com/voku/portable-ascii/issues", - "source": "https://github.com/voku/portable-ascii/tree/2.0.3" - }, - "funding": [ - { - "url": "https://www.paypal.me/moelleken", - "type": "custom" - }, - { - "url": "https://github.com/voku", - "type": "github" - }, - { - "url": "https://opencollective.com/portable-ascii", - "type": "open_collective" - }, - { - "url": "https://www.patreon.com/voku", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", - "type": "tidelift" - } - ], - "time": "2024-11-21T01:49:47+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "php": "^7.2 || ^8.0" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.11.0" - }, - "time": "2022-06-03T18:03:27+00:00" - } - ], - "packages-dev": [ - { - "name": "fakerphp/faker", - "version": "v1.24.1", - "source": { - "type": "git", - "url": "https://github.com/FakerPHP/Faker.git", - "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", - "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0", - "psr/container": "^1.0 || ^2.0", - "symfony/deprecation-contracts": "^2.2 || ^3.0" - }, - "conflict": { - "fzaninotto/faker": "*" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", - "doctrine/persistence": "^1.3 || ^2.0", - "ext-intl": "*", - "phpunit/phpunit": "^9.5.26", - "symfony/phpunit-bridge": "^5.4.16" - }, - "suggest": { - "doctrine/orm": "Required to use Faker\\ORM\\Doctrine", - "ext-curl": "Required by Faker\\Provider\\Image to download images.", - "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.", - "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.", - "ext-mbstring": "Required for multibyte Unicode string functionality." - }, - "type": "library", - "autoload": { - "psr-4": { - "Faker\\": "src/Faker/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "François Zaninotto" - } - ], - "description": "Faker is a PHP library that generates fake data for you.", - "keywords": [ - "data", - "faker", - "fixtures" - ], - "support": { - "issues": "https://github.com/FakerPHP/Faker/issues", - "source": "https://github.com/FakerPHP/Faker/tree/v1.24.1" - }, - "time": "2024-11-21T13:46:39+00:00" - }, - { - "name": "filp/whoops", - "version": "2.18.4", - "source": { - "type": "git", - "url": "https://github.com/filp/whoops.git", - "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/d2102955e48b9fd9ab24280a7ad12ed552752c4d", - "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0", - "psr/log": "^1.0.1 || ^2.0 || ^3.0" - }, - "require-dev": { - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3", - "symfony/var-dumper": "^4.0 || ^5.0" - }, - "suggest": { - "symfony/var-dumper": "Pretty print complex values better with var-dumper available", - "whoops/soap": "Formats errors as SOAP responses" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Whoops\\": "src/Whoops/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Filipe Dobreira", - "homepage": "https://github.com/filp", - "role": "Developer" - } - ], - "description": "php error handling for cool kids", - "homepage": "https://filp.github.io/whoops/", - "keywords": [ - "error", - "exception", - "handling", - "library", - "throwable", - "whoops" - ], - "support": { - "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.18.4" - }, - "funding": [ - { - "url": "https://github.com/denis-sokolov", - "type": "github" - } - ], - "time": "2025-08-08T12:00:00+00:00" - }, - { - "name": "hamcrest/hamcrest-php", - "version": "v2.1.1", - "source": { - "type": "git", - "url": "https://github.com/hamcrest/hamcrest-php.git", - "reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487", - "reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487", - "shasum": "" - }, - "require": { - "php": "^7.4|^8.0" - }, - "replace": { - "cordoval/hamcrest-php": "*", - "davedevelopment/hamcrest-php": "*", - "kodova/hamcrest-php": "*" - }, - "require-dev": { - "phpunit/php-file-iterator": "^1.4 || ^2.0 || ^3.0", - "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0 || ^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "autoload": { - "classmap": [ - "hamcrest" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "This is the PHP port of Hamcrest Matchers", - "keywords": [ - "test" - ], - "support": { - "issues": "https://github.com/hamcrest/hamcrest-php/issues", - "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.1.1" - }, - "time": "2025-04-30T06:54:44+00:00" - }, - { - "name": "laravel/pail", - "version": "v1.2.3", - "source": { - "type": "git", - "url": "https://github.com/laravel/pail.git", - "reference": "8cc3d575c1f0e57eeb923f366a37528c50d2385a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/pail/zipball/8cc3d575c1f0e57eeb923f366a37528c50d2385a", - "reference": "8cc3d575c1f0e57eeb923f366a37528c50d2385a", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "illuminate/console": "^10.24|^11.0|^12.0", - "illuminate/contracts": "^10.24|^11.0|^12.0", - "illuminate/log": "^10.24|^11.0|^12.0", - "illuminate/process": "^10.24|^11.0|^12.0", - "illuminate/support": "^10.24|^11.0|^12.0", - "nunomaduro/termwind": "^1.15|^2.0", - "php": "^8.2", - "symfony/console": "^6.0|^7.0" - }, - "require-dev": { - "laravel/framework": "^10.24|^11.0|^12.0", - "laravel/pint": "^1.13", - "orchestra/testbench-core": "^8.13|^9.0|^10.0", - "pestphp/pest": "^2.20|^3.0", - "pestphp/pest-plugin-type-coverage": "^2.3|^3.0", - "phpstan/phpstan": "^1.12.27", - "symfony/var-dumper": "^6.3|^7.0" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Laravel\\Pail\\PailServiceProvider" - ] - }, - "branch-alias": { - "dev-main": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Laravel\\Pail\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - }, - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "Easily delve into your Laravel application's log files directly from the command line.", - "homepage": "https://github.com/laravel/pail", - "keywords": [ - "dev", - "laravel", - "logs", - "php", - "tail" - ], - "support": { - "issues": "https://github.com/laravel/pail/issues", - "source": "https://github.com/laravel/pail" - }, - "time": "2025-06-05T13:55:57+00:00" - }, - { - "name": "laravel/pint", - "version": "v1.25.1", - "source": { - "type": "git", - "url": "https://github.com/laravel/pint.git", - "reference": "5016e263f95d97670d71b9a987bd8996ade6d8d9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/5016e263f95d97670d71b9a987bd8996ade6d8d9", - "reference": "5016e263f95d97670d71b9a987bd8996ade6d8d9", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-mbstring": "*", - "ext-tokenizer": "*", - "ext-xml": "*", - "php": "^8.2.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.87.2", - "illuminate/view": "^11.46.0", - "larastan/larastan": "^3.7.1", - "laravel-zero/framework": "^11.45.0", - "mockery/mockery": "^1.6.12", - "nunomaduro/termwind": "^2.3.1", - "pestphp/pest": "^2.36.0" - }, - "bin": [ - "builds/pint" - ], - "type": "project", - "autoload": { - "psr-4": { - "App\\": "app/", - "Database\\Seeders\\": "database/seeders/", - "Database\\Factories\\": "database/factories/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "An opinionated code formatter for PHP.", - "homepage": "https://laravel.com", - "keywords": [ - "format", - "formatter", - "lint", - "linter", - "php" - ], - "support": { - "issues": "https://github.com/laravel/pint/issues", - "source": "https://github.com/laravel/pint" - }, - "time": "2025-09-19T02:57:12+00:00" - }, - { - "name": "laravel/sail", - "version": "v1.46.0", - "source": { - "type": "git", - "url": "https://github.com/laravel/sail.git", - "reference": "eb90c4f113c4a9637b8fdd16e24cfc64f2b0ae6e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/sail/zipball/eb90c4f113c4a9637b8fdd16e24cfc64f2b0ae6e", - "reference": "eb90c4f113c4a9637b8fdd16e24cfc64f2b0ae6e", - "shasum": "" - }, - "require": { - "illuminate/console": "^9.52.16|^10.0|^11.0|^12.0", - "illuminate/contracts": "^9.52.16|^10.0|^11.0|^12.0", - "illuminate/support": "^9.52.16|^10.0|^11.0|^12.0", - "php": "^8.0", - "symfony/console": "^6.0|^7.0", - "symfony/yaml": "^6.0|^7.0" - }, - "require-dev": { - "orchestra/testbench": "^7.0|^8.0|^9.0|^10.0", - "phpstan/phpstan": "^1.10" - }, - "bin": [ - "bin/sail" - ], - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Laravel\\Sail\\SailServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Laravel\\Sail\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "Docker files for running a basic Laravel application.", - "keywords": [ - "docker", - "laravel" - ], - "support": { - "issues": "https://github.com/laravel/sail/issues", - "source": "https://github.com/laravel/sail" - }, - "time": "2025-09-23T13:44:39+00:00" - }, - { - "name": "mockery/mockery", - "version": "1.6.12", - "source": { - "type": "git", - "url": "https://github.com/mockery/mockery.git", - "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mockery/mockery/zipball/1f4efdd7d3beafe9807b08156dfcb176d18f1699", - "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699", - "shasum": "" - }, - "require": { - "hamcrest/hamcrest-php": "^2.0.1", - "lib-pcre": ">=7.0", - "php": ">=7.3" - }, - "conflict": { - "phpunit/phpunit": "<8.0" - }, - "require-dev": { - "phpunit/phpunit": "^8.5 || ^9.6.17", - "symplify/easy-coding-standard": "^12.1.14" - }, - "type": "library", - "autoload": { - "files": [ - "library/helpers.php", - "library/Mockery.php" - ], - "psr-4": { - "Mockery\\": "library/Mockery" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Pádraic Brady", - "email": "padraic.brady@gmail.com", - "homepage": "https://github.com/padraic", - "role": "Author" - }, - { - "name": "Dave Marshall", - "email": "dave.marshall@atstsolutions.co.uk", - "homepage": "https://davedevelopment.co.uk", - "role": "Developer" - }, - { - "name": "Nathanael Esayeas", - "email": "nathanael.esayeas@protonmail.com", - "homepage": "https://github.com/ghostwriter", - "role": "Lead Developer" - } - ], - "description": "Mockery is a simple yet flexible PHP mock object framework", - "homepage": "https://github.com/mockery/mockery", - "keywords": [ - "BDD", - "TDD", - "library", - "mock", - "mock objects", - "mockery", - "stub", - "test", - "test double", - "testing" - ], - "support": { - "docs": "https://docs.mockery.io/", - "issues": "https://github.com/mockery/mockery/issues", - "rss": "https://github.com/mockery/mockery/releases.atom", - "security": "https://github.com/mockery/mockery/security/advisories", - "source": "https://github.com/mockery/mockery" - }, - "time": "2024-05-16T03:13:13+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.13.4", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", - "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3 <3.2.2" - }, - "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpspec/prophecy": "^1.10", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" - }, - "type": "library", - "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2025-08-01T08:46:24+00:00" - }, - { - "name": "nunomaduro/collision", - "version": "v8.8.2", - "source": { - "type": "git", - "url": "https://github.com/nunomaduro/collision.git", - "reference": "60207965f9b7b7a4ce15a0f75d57f9dadb105bdb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/60207965f9b7b7a4ce15a0f75d57f9dadb105bdb", - "reference": "60207965f9b7b7a4ce15a0f75d57f9dadb105bdb", - "shasum": "" - }, - "require": { - "filp/whoops": "^2.18.1", - "nunomaduro/termwind": "^2.3.1", - "php": "^8.2.0", - "symfony/console": "^7.3.0" - }, - "conflict": { - "laravel/framework": "<11.44.2 || >=13.0.0", - "phpunit/phpunit": "<11.5.15 || >=13.0.0" - }, - "require-dev": { - "brianium/paratest": "^7.8.3", - "larastan/larastan": "^3.4.2", - "laravel/framework": "^11.44.2 || ^12.18", - "laravel/pint": "^1.22.1", - "laravel/sail": "^1.43.1", - "laravel/sanctum": "^4.1.1", - "laravel/tinker": "^2.10.1", - "orchestra/testbench-core": "^9.12.0 || ^10.4", - "pestphp/pest": "^3.8.2", - "sebastian/environment": "^7.2.1 || ^8.0" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" - ] - }, - "branch-alias": { - "dev-8.x": "8.x-dev" - } - }, - "autoload": { - "files": [ - "./src/Adapters/Phpunit/Autoload.php" - ], - "psr-4": { - "NunoMaduro\\Collision\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "Cli error handling for console/command-line PHP applications.", - "keywords": [ - "artisan", - "cli", - "command-line", - "console", - "dev", - "error", - "handling", - "laravel", - "laravel-zero", - "php", - "symfony" - ], - "support": { - "issues": "https://github.com/nunomaduro/collision/issues", - "source": "https://github.com/nunomaduro/collision" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - }, - { - "url": "https://www.patreon.com/nunomaduro", - "type": "patreon" - } - ], - "time": "2025-06-25T02:12:12+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "54750ef60c58e43759730615a392c31c80e23176" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", - "reference": "54750ef60c58e43759730615a392c31c80e23176", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2024-03-03T12:33:53+00:00" - }, - { - "name": "phar-io/version", - "version": "3.2.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.2.1" - }, - "time": "2022-02-21T01:04:05+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "11.0.11", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "4f7722aa9a7b76aa775e2d9d4e95d1ea16eeeef4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4f7722aa9a7b76aa775e2d9d4e95d1ea16eeeef4", - "reference": "4f7722aa9a7b76aa775e2d9d4e95d1ea16eeeef4", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^5.4.0", - "php": ">=8.2", - "phpunit/php-file-iterator": "^5.1.0", - "phpunit/php-text-template": "^4.0.1", - "sebastian/code-unit-reverse-lookup": "^4.0.1", - "sebastian/complexity": "^4.0.1", - "sebastian/environment": "^7.2.0", - "sebastian/lines-of-code": "^3.0.1", - "sebastian/version": "^5.0.2", - "theseer/tokenizer": "^1.2.3" - }, - "require-dev": { - "phpunit/phpunit": "^11.5.2" - }, - "suggest": { - "ext-pcov": "PHP extension that provides line coverage", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "11.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "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/11.0.11" - }, - "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/phpunit/php-code-coverage", - "type": "tidelift" - } - ], - "time": "2025-08-27T14:37:49+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "5.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", - "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-08-27T05:02:59+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "5.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", - "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^11.0" - }, - "suggest": { - "ext-pcntl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", - "keywords": [ - "process" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:07:44+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "4.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", - "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:08:43+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "7.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", - "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "7.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "security": "https://github.com/sebastianbergmann/php-timer/security/policy", - "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:09:35+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "11.5.42", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "1c6cb5dfe412af3d0dfd414cfd110e3b9cfdbc3c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1c6cb5dfe412af3d0dfd414cfd110e3b9cfdbc3c", - "reference": "1c6cb5dfe412af3d0dfd414cfd110e3b9cfdbc3c", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.13.4", - "phar-io/manifest": "^2.0.4", - "phar-io/version": "^3.2.1", - "php": ">=8.2", - "phpunit/php-code-coverage": "^11.0.11", - "phpunit/php-file-iterator": "^5.1.0", - "phpunit/php-invoker": "^5.0.1", - "phpunit/php-text-template": "^4.0.1", - "phpunit/php-timer": "^7.0.1", - "sebastian/cli-parser": "^3.0.2", - "sebastian/code-unit": "^3.0.3", - "sebastian/comparator": "^6.3.2", - "sebastian/diff": "^6.0.2", - "sebastian/environment": "^7.2.1", - "sebastian/exporter": "^6.3.2", - "sebastian/global-state": "^7.0.2", - "sebastian/object-enumerator": "^6.0.1", - "sebastian/type": "^5.1.3", - "sebastian/version": "^5.0.2", - "staabm/side-effects-detector": "^1.0.5" - }, - "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "11.5-dev" - } - }, - "autoload": { - "files": [ - "src/Framework/Assert/Functions.php" - ], - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.42" - }, - "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "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/phpunit/phpunit", - "type": "tidelift" - } - ], - "time": "2025-09-28T12:09:13+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", - "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", - "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/3.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:41:36+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/54391c61e4af8078e5b276ab082b6d3c54c9ad64", - "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "security": "https://github.com/sebastianbergmann/code-unit/security/policy", - "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2025-03-19T07:56:08+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "4.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "183a9b2632194febd219bb9246eee421dad8d45e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", - "reference": "183a9b2632194febd219bb9246eee421dad8d45e", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:45:54+00:00" - }, - { - "name": "sebastian/comparator", - "version": "6.3.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "85c77556683e6eee4323e4c5468641ca0237e2e8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/85c77556683e6eee4323e4c5468641ca0237e2e8", - "reference": "85c77556683e6eee4323e4c5468641ca0237e2e8", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-mbstring": "*", - "php": ">=8.2", - "sebastian/diff": "^6.0", - "sebastian/exporter": "^6.0" - }, - "require-dev": { - "phpunit/phpunit": "^11.4" - }, - "suggest": { - "ext-bcmath": "For comparing BcMath\\Number objects" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.3-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/comparator/issues", - "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.2" - }, - "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/comparator", - "type": "tidelift" - } - ], - "time": "2025-08-10T08:07:46+00:00" - }, - { - "name": "sebastian/complexity", - "version": "4.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", - "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^5.0", - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", - "support": { - "issues": "https://github.com/sebastianbergmann/complexity/issues", - "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:49:50+00:00" - }, - { - "name": "sebastian/diff", - "version": "6.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", - "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:53:05+00:00" - }, - { - "name": "sebastian/environment", - "version": "7.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/a5c75038693ad2e8d4b6c15ba2403532647830c4", - "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.3" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "7.2-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "https://github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/7.2.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/environment", - "type": "tidelift" - } - ], - "time": "2025-05-21T11:55:47+00:00" - }, - { - "name": "sebastian/exporter", - "version": "6.3.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "70a298763b40b213ec087c51c739efcaa90bcd74" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/70a298763b40b213ec087c51c739efcaa90bcd74", - "reference": "70a298763b40b213ec087c51c739efcaa90bcd74", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": ">=8.2", - "sebastian/recursion-context": "^6.0" - }, - "require-dev": { - "phpunit/phpunit": "^11.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.3-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "https://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.2" - }, - "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/exporter", - "type": "tidelift" - } - ], - "time": "2025-09-24T06:12:51+00:00" - }, - { - "name": "sebastian/global-state", - "version": "7.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "3be331570a721f9a4b5917f4209773de17f747d7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", - "reference": "3be331570a721f9a4b5917f4209773de17f747d7", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "sebastian/object-reflector": "^4.0", - "sebastian/recursion-context": "^6.0" - }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "7.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "https://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "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/7.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:57:36+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", - "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^5.0", - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for counting the lines of code in PHP source code", - "homepage": "https://github.com/sebastianbergmann/lines-of-code", - "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/3.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:58:38+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "6.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "f5b498e631a74204185071eb41f33f38d64608aa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", - "reference": "f5b498e631a74204185071eb41f33f38d64608aa", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "sebastian/object-reflector": "^4.0", - "sebastian/recursion-context": "^6.0" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:00:13+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "4.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", - "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:01:32+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "6.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/f6458abbf32a6c8174f8f26261475dc133b3d9dc", - "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "https://github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.3" - }, - "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/recursion-context", - "type": "tidelift" - } - ], - "time": "2025-08-13T04:42:22+00:00" - }, - { - "name": "sebastian/type", - "version": "5.1.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/f77d2d4e78738c98d9a68d2596fe5e8fa380f449", - "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Collection of value objects that represent the types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", - "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "security": "https://github.com/sebastianbergmann/type/security/policy", - "source": "https://github.com/sebastianbergmann/type/tree/5.1.3" - }, - "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/type", - "type": "tidelift" - } - ], - "time": "2025-08-09T06:55:48+00:00" - }, - { - "name": "sebastian/version", - "version": "5.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", - "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "security": "https://github.com/sebastianbergmann/version/security/policy", - "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-10-09T05:16:32+00:00" - }, - { - "name": "staabm/side-effects-detector", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/staabm/side-effects-detector.git", - "reference": "d8334211a140ce329c13726d4a715adbddd0a163" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", - "reference": "d8334211a140ce329c13726d4a715adbddd0a163", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^1.12.6", - "phpunit/phpunit": "^9.6.21", - "symfony/var-dumper": "^5.4.43", - "tomasvotruba/type-coverage": "1.0.0", - "tomasvotruba/unused-public": "1.0.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "lib/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A static analysis tool to detect side effects in PHP code", - "keywords": [ - "static analysis" - ], - "support": { - "issues": "https://github.com/staabm/side-effects-detector/issues", - "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" - }, - "funding": [ - { - "url": "https://github.com/staabm", - "type": "github" - } - ], - "time": "2024-10-20T05:08:20+00:00" - }, - { - "name": "symfony/yaml", - "version": "v7.3.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "d4f4a66866fe2451f61296924767280ab5732d9d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/d4f4a66866fe2451f61296924767280ab5732d9d", - "reference": "d4f4a66866fe2451f61296924767280ab5732d9d", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "symfony/console": "<6.4" - }, - "require-dev": { - "symfony/console": "^6.4|^7.0" - }, - "bin": [ - "Resources/bin/yaml-lint" - ], - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Loads and dumps YAML files", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/yaml/tree/v7.3.3" - }, - "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": "2025-08-27T11:34:33+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.3", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", - "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "support": { - "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.3" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2024-03-03T12:36:25+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": {}, - "prefer-stable": true, - "prefer-lowest": false, - "platform": { - "php": "^8.2" - }, - "platform-dev": {}, - "plugin-api-version": "2.6.0" -}