66
77use Generator ;
88use Illuminate \Support \Facades \File ;
9+ use Illuminate \Support \Facades \Http ;
910use Illuminate \Support \Facades \Process ;
1011use Laravel \Mcp \Server \Tool ;
1112use Laravel \Mcp \Server \Tools \ToolInputSchema ;
1213use Laravel \Mcp \Server \Tools \ToolResult ;
1314
1415class InstallRestifyTool extends Tool
1516{
17+ private const LATEST_CONFIG_URL = 'https://raw.githubusercontent.com/BinarCode/laravel-restify/refs/heads/10.x/config/restify.php ' ;
18+
1619 public function description (): string
1720 {
18- return 'Install and setup Laravel Restify package with all necessary configurations. This tool handles composer installation, publishes config files , runs setup commands, creates the Restify service provider, scaffolds repositories, and optionally configures authentication middleware and generates mock data. ' ;
21+ return 'Install and setup Laravel Restify package with all necessary configurations. This tool handles composer installation, downloads the latest config file from Laravel Restify 10.x , runs setup commands, creates the Restify service provider, scaffolds repositories, and optionally configures authentication middleware and generates mock data. ' ;
1922 }
2023
2124 public function schema (ToolInputSchema $ schema ): ToolInputSchema
@@ -41,6 +44,9 @@ public function schema(ToolInputSchema $schema): ToolInputSchema
4144 ->optional ()
4245 ->boolean ('force ' )
4346 ->description ('Force installation even if already installed ' )
47+ ->optional ()
48+ ->boolean ('update_config ' )
49+ ->description ('Download and use the latest config file from Laravel Restify 10.x (default: true) ' )
4450 ->optional ();
4551 }
4652
@@ -54,6 +60,7 @@ public function handle(array $arguments): ToolResult|Generator
5460 $ generateUsersCount = $ arguments ['generate_users_count ' ] ?? 0 ;
5561 $ generateRepositories = $ arguments ['generate_repositories ' ] ?? false ;
5662 $ force = $ arguments ['force ' ] ?? false ;
63+ $ updateConfig = $ arguments ['update_config ' ] ?? true ;
5764
5865 // Step 1: Validate environment
5966 $ validationResult = $ this ->validateEnvironment ();
@@ -84,6 +91,12 @@ public function handle(array $arguments): ToolResult|Generator
8491 return ToolResult::error ($ setupResult ['message ' ]);
8592 }
8693
94+ // Step 4.5: Update config file with latest version
95+ if ($ updateConfig ) {
96+ $ configResult = $ this ->updateConfigFile ();
97+ $ results [] = $ configResult ;
98+ }
99+
87100 // Step 5: Configure options
88101 if ($ enableSanctumAuth ) {
89102 $ results [] = $ this ->enableSanctumAuthentication ();
@@ -229,6 +242,144 @@ protected function runRestifySetup(): array
229242 }
230243 }
231244
245+ protected function updateConfigFile (): array
246+ {
247+ try {
248+ $ configPath = config_path ('restify.php ' );
249+ $ existingConfig = null ;
250+ $ backupCreated = false ;
251+
252+ // Backup existing config if it exists
253+ if (File::exists ($ configPath )) {
254+ $ existingConfig = File::get ($ configPath );
255+ $ backupPath = $ configPath . '.backup- ' . date ('Y-m-d-H-i-s ' );
256+ File::copy ($ configPath , $ backupPath );
257+ $ backupCreated = true ;
258+ }
259+
260+ // Download latest config file
261+ $ response = Http::timeout (30 )->get (self ::LATEST_CONFIG_URL );
262+
263+ if (!$ response ->successful ()) {
264+ return [
265+ 'success ' => false ,
266+ 'step ' => 'Config Update ' ,
267+ 'message ' => 'Failed to download latest config file: HTTP ' . $ response ->status (),
268+ ];
269+ }
270+
271+ $ latestConfig = $ response ->body ();
272+
273+ // If we have existing config, try to preserve custom settings
274+ if ($ existingConfig && $ this ->configsAreDifferent ($ existingConfig , $ latestConfig )) {
275+ $ mergedConfig = $ this ->mergeConfigFiles ($ existingConfig , $ latestConfig );
276+ File::put ($ configPath , $ mergedConfig );
277+
278+ $ message = $ backupCreated
279+ ? 'Updated config file with latest version (backup created) '
280+ : 'Updated config file with latest version ' ;
281+ } else {
282+ // Use the latest config as-is
283+ File::put ($ configPath , $ latestConfig );
284+ $ message = 'Downloaded and installed latest config file ' ;
285+ }
286+
287+ return [
288+ 'success ' => true ,
289+ 'step ' => 'Config Update ' ,
290+ 'message ' => $ message ,
291+ 'backup_created ' => $ backupCreated ,
292+ ];
293+
294+ } catch (\Exception $ e ) {
295+ return [
296+ 'success ' => false ,
297+ 'step ' => 'Config Update ' ,
298+ 'message ' => 'Failed to update config file: ' . $ e ->getMessage (),
299+ ];
300+ }
301+ }
302+
303+ protected function configsAreDifferent (string $ existing , string $ latest ): bool
304+ {
305+ // Simple comparison - if they're identical, no need to merge
306+ return trim ($ existing ) !== trim ($ latest );
307+ }
308+
309+ protected function mergeConfigFiles (string $ existing , string $ latest ): string
310+ {
311+ try {
312+ // Extract custom values from existing config
313+ $ customValues = $ this ->extractCustomValues ($ existing );
314+
315+ // Start with the latest config
316+ $ mergedConfig = $ latest ;
317+
318+ // Apply custom values to the latest config
319+ foreach ($ customValues as $ key => $ value ) {
320+ $ mergedConfig = $ this ->replaceConfigValue ($ mergedConfig , $ key , $ value );
321+ }
322+
323+ // Add a comment indicating the merge
324+ $ timestamp = date ('Y-m-d H:i:s ' );
325+ $ mergedConfig = str_replace (
326+ '<?php ' ,
327+ "<?php \n\n// This config was merged with custom values on {$ timestamp }\n// Original backed up to restify.php.backup- {$ timestamp }" ,
328+ $ mergedConfig
329+ );
330+
331+ return $ mergedConfig ;
332+
333+ } catch (\Exception $ e ) {
334+ // If merge fails, return the latest config with a warning comment
335+ return str_replace (
336+ '<?php ' ,
337+ "<?php \n\n// Warning: Config merge failed, using latest version. \n// Check backup file for your custom settings. " ,
338+ $ latest
339+ );
340+ }
341+ }
342+
343+ protected function extractCustomValues (string $ config ): array
344+ {
345+ $ customValues = [];
346+
347+ // Extract commonly customized values
348+ $ patterns = [
349+ 'base ' => "/'base'\s*=>\s*'([^']+)'/ " ,
350+ 'middleware ' => "/'middleware'\s*=>\s*(\[[^\]]*\])/s " ,
351+ 'auth ' => "/'auth'\s*=>\s*(\[[^\]]*\])/s " ,
352+ 'cache ' => "/'cache'\s*=>\s*(\[[^\]]*\])/s " ,
353+ ];
354+
355+ foreach ($ patterns as $ key => $ pattern ) {
356+ if (preg_match ($ pattern , $ config , $ matches )) {
357+ $ customValues [$ key ] = $ key === 'base ' ? $ matches [1 ] : $ matches [0 ];
358+ }
359+ }
360+
361+ return $ customValues ;
362+ }
363+
364+ protected function replaceConfigValue (string $ config , string $ key , string $ value ): string
365+ {
366+ switch ($ key ) {
367+ case 'base ' :
368+ return preg_replace (
369+ "/'base'\s*=>\s*'[^']+'/ " ,
370+ "'base' => ' {$ value }' " ,
371+ $ config
372+ );
373+ case 'middleware ' :
374+ case 'auth ' :
375+ case 'cache ' :
376+ $ pattern = "/' $ key'\s*=>\s*\[[^\]]*\]/s " ;
377+ return preg_replace ($ pattern , $ value , $ config );
378+ default :
379+ return $ config ;
380+ }
381+ }
382+
232383 protected function enableSanctumAuthentication (): array
233384 {
234385 try {
@@ -454,14 +605,22 @@ protected function generateSuccessResponse(array $results, array $arguments): To
454605 $ response .= "✅ **Repositories:** Auto-generated for existing models \n" ;
455606 }
456607
608+ if ($ arguments ['update_config ' ] ?? true ) {
609+ $ response .= "✅ **Config File:** Updated with latest Laravel Restify 10.x configuration \n" ;
610+ }
611+
457612 // What was created
458- $ response .= "\n## Files Created \n\n" ;
459- $ response .= "- `config/restify.php` - Main configuration file \n" ;
613+ $ response .= "\n## Files Created/Updated \n\n" ;
614+ $ response .= "- `config/restify.php` - Latest configuration file (v10.x) \n" ;
460615 $ response .= "- `app/Providers/RestifyServiceProvider.php` - Service provider \n" ;
461616 $ response .= "- `app/Restify/` - Repository directory \n" ;
462617 $ response .= "- `app/Restify/Repository.php` - Base repository class \n" ;
463618 $ response .= "- `app/Restify/UserRepository.php` - User repository example \n" ;
464619 $ response .= "- Database migration for action logs \n" ;
620+
621+ if ($ arguments ['update_config ' ] ?? true ) {
622+ $ response .= "- `config/restify.php.backup-*` - Backup of previous config (if existed) \n" ;
623+ }
465624
466625 // API endpoints
467626 $ apiPrefix = $ arguments ['api_prefix ' ] ?? '/api/restify ' ;
@@ -478,12 +637,13 @@ protected function generateSuccessResponse(array $results, array $arguments): To
478637 // Next steps
479638 $ response .= "\n## Next Steps \n\n" ;
480639 $ response .= "1. **Test the API:** Make a GET request to ` {$ apiPrefix }/users` \n" ;
481- $ response .= "2. **Create more repositories:** `php artisan restify:repository PostRepository` \n" ;
482- $ response .= "3. **Generate policies:** `php artisan restify:policy UserPolicy` \n" ;
483- $ response .= "4. **Review documentation:** https://restify.binarcode.com \n" ;
640+ $ response .= "2. **Review config file:** Check `config/restify.php` for the latest features \n" ;
641+ $ response .= "3. **Create more repositories:** `php artisan restify:repository PostRepository` \n" ;
642+ $ response .= "4. **Generate policies:** `php artisan restify:policy UserPolicy` \n" ;
643+ $ response .= "5. **Review documentation:** https://restify.binarcode.com \n" ;
484644
485645 if ($ arguments ['enable_sanctum_auth ' ] ?? false ) {
486- $ response .= "5 . **Configure Sanctum:** Ensure Laravel Sanctum is properly set up \n" ;
646+ $ response .= "6 . **Configure Sanctum:** Ensure Laravel Sanctum is properly set up \n" ;
487647 }
488648
489649 // Authentication note
@@ -505,7 +665,9 @@ protected function generateSuccessResponse(array $results, array $arguments): To
505665 $ response .= "# Generate mock data \n" ;
506666 $ response .= "php artisan restify:stub users --count=50 \n\n" ;
507667 $ response .= "# Generate policy \n" ;
508- $ response .= "php artisan restify:policy PostPolicy \n" ;
668+ $ response .= "php artisan restify:policy PostPolicy \n\n" ;
669+ $ response .= "# Republish config file (to get latest updates) \n" ;
670+ $ response .= "php artisan vendor:publish --provider= \"Binaryk \\LaravelRestify \\LaravelRestifyServiceProvider \" --tag=config --force \n" ;
509671 $ response .= "``` \n" ;
510672
511673 return ToolResult::text ($ response );
0 commit comments