Tärkeimmät takeaways Laravel Prompts tarjoaa kauniin, käyttäjäystävällisen käyttöliittymän komentosarjojen sovelluksiin, joilla ei ole riippuvuuksia Paketti tarjoaa useita syöttötyyppejä, mukaan lukien teksti, salasana, valitse, valitse, vahvista, etsi ja edistymispalkit Laravel 12 sisältää Prompts natiivisesti, mikä tekee CLI-yhteyksistä intuitiivisempia ja visuaalisesti houkuttelevia Prompts käsittelee automaattisesti validointia, virheilmoituksia ja näppäimistön navigointia Täydellinen asennusoppaiden, konfigurointityökalujen ja vuorovaikutteisten käsityökomentojen luomiseen indeksiä Pääartikkeli: Laravel Prompts Laravel Prompts -komponentit Tilastot Käytettävissä olevat nopeat tyypit Käytännön toteutus: Database Seeder Generator Mielenkiintoisia faktoja parhaita käytäntöjä ja FAQ Johtopäätös Pääartikkeli: Laravel Prompts Laravel Prompts on PHP-paketti, joka on suunniteltu lisäämään kauniita ja käyttäjäystävällisiä lomakkeita komentosarjojen sovelluksiin. Laravel 10: ssä esitelty ja täysin integroitu Laravel 12: een, se muuttaa tapaa, jolla kehittäjät rakentavat vuorovaikutteisia CLI-työkaluja. Laravel Promptsin kauneus on sen yksinkertaisuudessa. Kehittäjien ei tarvitse enää huolehtia kursorin sijoittamisesta, syöttövalidoinnin muotoilusta tai alustojen välisestä yhteensopivuudesta. Kaikki toimii saumattomasti laatikon ulkopuolella, jolloin voit keskittyä rakennusominaisuuksiin sen sijaan, että taistelisit terminaaliin. Laravel Prompts -komponentit Laravel Prompts koostuu useista ydinkomponenteista, jotka toimivat yhdessä luodakseen vuorovaikutteisia kokemuksia. Sen perustana on paketti, jossa käytetään renderin, joka käsittelee visuaalisen esityksen kehotuksia eri päätelaitteiden emulaattoreita. Syöttö käsittelee näppäimistön tapahtumia, joka tukee sekä nuolinäppäimiä että vim-tyylistä navigointia. Validointijärjestelmä integroituu saumattomasti Laravelin olemassa oleviin validointisääntöihin. Voit soveltaa samaa validointilogiikkaa, jota käytät web-lomakkeissa, CLI-huomautuksiin. Virheilmoitukset näkyvät verkossa, mikä antaa välitöntä palautetta häiritsemättä käyttäjän virtausta. Tekstin syöttöt käsittelevät yhden rivin vastauksia, valitut pudotukset esittävät valintoja tyylikkäästi ja edistymispalkit antavat visuaalista palautetta pitkien toimintojen aikana. Tilastot Paketin hyväksyminen ja suorituskyvyn mittarit: Laravel Prompts on ladattu yli 15 miljoonaa kertaa sen julkaisun jälkeen (Lähde: Packagist.org) Paketti tukee PHP 8.1+ ja toimii Windows, macOS ja Linux ympäristöissä Laravel 12 sisältää Promptsin ensimmäisen osapuolen pakettina, joka on integroitu suoraan kehykseen Yli 2000+ GitHub-tähteä virallisessa tallennuksessa, mikä osoittaa vahvan yhteisön hyväksynnän (Lähde: GitHub Laravel Prompts) Pakkauksessa on nolla käynnistysajan riippuvuutta, mikä pitää sovelluksesi kevyenä Pakkaaminen.org Pääartikkeli: GitHub Laravel Prompts Käytettävissä olevat nopeat tyypit Laravel Prompts tarjoaa kahdeksan erilaista kyselytyyppiä, joista kukin on optimoitu tiettyihin vuorovaikutuksiin: Tekstin syöttö käsittelee yhden rivin tekstin syöttöä, jossa on sijaintituki ja reaaliaikainen validointi. Käytä sitä nimien, URL-osoitteiden tai lyhyen rivin syöttöön. Textarea tarjoaa usean rivin syöttöominaisuuksia, jotka sopivat täydellisesti kuvauksiin tai pidempään tekstisisältöön.Käyttäjät voivat navigoida nuolinäppäimillä ja lähettää Ctrl+D:llä. Salasana peittää merkkejä kirjoittamisen aikana, jotka ovat välttämättömiä arkaluonteisille tiedoille.Paketti varmistaa, että salasanojen kentät eivät koskaan kirjaudu sisään tai näytä niiden sisältöä. Vahvista esittää kyllä/ei kysymyksiä näppäimistön pikakuvakkeilla. Käyttäjät voivat painaa Y/N:ää tai valita valintansa käyttämällä nuolinäppäimiä. Select luo ponnahdusvalikoimia, joissa voit valita ennalta määritellyistä vaihtoehdoista.Se tukee näppäimistön navigointia ja hakutoimintoa pidemmille luetteloille. Multiselectin avulla voit valita useita kohteita luettelosta käyttämällä välilyöntialuetta. Ihanteellinen ominaisuuksien tai luokkien valintaan. Haku yhdistää tekstin syöttöön dynaamisen suodattamisen, joka on ihanteellinen valintaan suurista tietokokonaisuuksista ilman, että käyttäjä on ylivoimainen. Edistymispalkit visualisoivat pitkän aikavälin tehtäviä ja päivittävät ne automaattisesti, kun toiminto on valmis. Käytännön toteutus: Database Seeder Generator Rakennetaan reaalimaailman esimerkki: vuorovaikutteinen tietokannan kylväjägeneraattori, joka auttaa kehittäjiä täyttämään sovelluksensa nopeasti testitiedoilla. Tämän ohjaimen avulla kehittäjät voivat valita, mitkä mallit kylvää, konfiguroida tietueita, luoda suhteita ja tallentaa konfiguraatioita uudelleenkäytettäviksi esiasetuksiksi - kaikki tyylikkään komentosarjan käyttöliittymän kautta. Edellytykset Ennen tämän siemengeneraattorin käyttöönottoa varmista, että sinulla on: Siirrettiin kaikki tarvittavat tietokantataulukot - Avaa php käsityöläinen siirtyminen malleillesi (käyttäjät, viestit, kommentit, luokat jne.) Luodut mallit, joissa on asianmukaiset suhteet - Määritä HasMany, BelongsTo ja BelongsToMany suhteet malleissasi Aseta mallitehtaat - Luo tehtaita jokaiselle mallille käyttämällä php artisan make:factory ModelNameFactory Määriteltyjä täytettäviä ominaisuuksia - Varmista, että malleillasi on $täytettäviä ominaisuuksia joukkovelkakirjoittamiseen Kun tietokannan rakenne, mallit, suhteet ja tehtaat ovat valmiita, luo komento: php artisan make:command GenerateSeeder Täydellinen siemengeneraattori <?php namespace App\Console\Commands; use Illuminate\Console\Command; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; use Illuminate\Support\Str; use function Laravel\Prompts\multiselect; use function Laravel\Prompts\text; use function Laravel\Prompts\select; use function Laravel\Prompts\confirm; use function Laravel\Prompts\info; use function Laravel\Prompts\warning; use function Laravel\Prompts\error; use function Laravel\Prompts\table; use function Laravel\Prompts\spin; class GenerateSeeder extends Command { protected $signature = 'seed:generate {--preset=}'; protected $description = 'Interactive database seeder generator'; private array $availableModels = [ 'User' => \App\Models\User::class, 'Post' => \App\Models\Post::class, 'Comment' => \App\Models\Comment::class, 'Category' => \App\Models\Category::class, 'Product' => \App\Models\Product::class, 'Order' => \App\Models\Order::class, 'Tag' => \App\Models\Tag::class, ]; private array $config = []; public function handle() { info('🌱 Interactive Database Seeder Generator'); if ($this->option('preset')) { if ($this->loadPreset($this->option('preset'))) { info("✅ Loaded preset: {$this->option('preset')}"); $this->showPresetSummary(); if (confirm('Use this preset configuration?', default: true)) { if ($this->confirmExecution()) { $this->executeSeed(); } return 0; } } } $selectedModels = $this->selectModels(); if (empty($selectedModels)) { warning('No models selected. Exiting.'); return 0; } $this->configureCounts($selectedModels); $this->configureRelationships($selectedModels); $this->configureOptions(); $this->handleExistingData(); $this->showSummary(); if ($this->confirmExecution()) { $this->executeSeed(); $this->offerToSave(); } else { warning('⚠️ Seeding cancelled.'); } return 0; } private function selectModels(): array { $selectedKeys = multiselect( label: 'Which models do you want to seed?', options: $this->availableModels, hint: 'Use space to select, enter to confirm' ); $models = array_map(fn($key) => $this->availableModels[$key], $selectedKeys); return $this->checkDependencies($models); } private function checkDependencies(array $models): array { $dependencies = [ 'Comment' => ['Post'], 'Post' => ['User'], 'Order' => ['User', 'Product'], ]; foreach ($models as $model) { $modelName = class_basename($model); if (isset($dependencies[$modelName])) { foreach ($dependencies[$modelName] as $required) { $requiredClass = $this->availableModels[$required] ?? null; if ($requiredClass && !in_array($requiredClass, $models)) { warning("⚠️ {$modelName} requires {$required}."); if (confirm("Would you like to auto-include {$required}?", default: true)) { $models[] = $requiredClass; info("✅ Added {$required} to seeding list."); } } } } } return array_unique($models); } private function configureCounts(array $models): void { info('📊 Configure Record Counts'); foreach ($models as $model) { $modelName = class_basename($model); $count = text( label: "How many {$modelName} records?", default: $this->getDefaultCount($modelName), required: true, validate: fn($value) => is_numeric($value) && $value > 0 ? null : 'Please enter a valid number greater than 0', hint: $this->getCountHint($modelName) ); $this->config['models'][$modelName] = [ 'class' => $model, 'count' => (int)$count, ]; } } private function configureRelationships(array $models): void { info('🔗 Configure Relationships'); $modelNames = array_map(fn($m) => class_basename($m), $models); if (in_array('Post', $modelNames) && in_array('Category', $modelNames)) { $categoryAssignment = select( label: 'Assign Posts to Categories?', options: [ 'multiple' => 'Yes, assign each post to 1-3 categories (random)', 'single' => 'Yes, assign each post to exactly 1 category', 'none' => 'No, leave categories unassigned' ], default: 'multiple' ); $this->config['relationships']['post_category'] = $categoryAssignment; } if (in_array('Comment', $modelNames) && in_array('User', $modelNames)) { $commentAuthors = select( label: 'Who should author comments?', options: [ 'all' => 'Any user (random)', 'subset' => 'Only 30% of users are active commenters', 'post_author' => 'Include self-comments from post authors' ], default: 'all' ); $this->config['relationships']['comment_user'] = $commentAuthors; } } private function configureOptions(): void { info('⚙️ Additional Options'); $realism = select( label: 'Data realism level', options: [ 'high' => 'High (slower, more realistic data)', 'medium' => 'Medium (balanced)', 'low' => 'Low (fast, simple data)' ], default: 'medium', hint: 'Higher realism uses more varied faker data' ); $this->config['options']['realism'] = $realism; $specialCases = multiselect( label: 'Include special test cases?', options: [ 'admin' => 'Create 1 admin user', 'empty_users' => 'Create 5 users with no posts', 'featured' => 'Create 3 featured posts', 'suspended' => 'Create 2 suspended users', ], hint: 'Optional - adds specific edge cases for testing' ); $this->config['options']['special_cases'] = $specialCases; if (isset($this->config['models']['User'])) { info('👥 User States Distribution'); $activePercent = text( label: 'Percentage of active users', default: '80', validate: fn($v) => is_numeric($v) && $v >= 0 && $v <= 100 ? null : 'Enter 0-100' ); $this->config['options']['user_states'] = [ 'active' => (int)$activePercent, 'inactive' => 100 - (int)$activePercent ]; } } private function handleExistingData(): void { $hasData = false; foreach ($this->config['models'] as $modelName => $data) { $tableName = Str::snake(Str::plural($modelName)); if (Schema::hasTable($tableName)) { if (DB::table($tableName)->count() > 0) { $hasData = true; break; } } } if ($hasData) { warning('⚠️ Database already contains data.'); $action = select( label: 'What should we do?', options: [ 'append' => 'Add new records (append)', 'truncate' => 'Truncate tables first (clean start)', 'skip' => 'Cancel seeding' ], default: 'append' ); $this->config['options']['existing_data'] = $action; if ($action === 'skip') { warning('Seeding cancelled.'); exit(0); } } } private function showSummary(): void { info(''); info('═══════════════════════════════════════════════════'); info(' 📊 Seeding Summary'); info('═══════════════════════════════════════════════════'); $tableData = []; $totalRecords = 0; foreach ($this->config['models'] as $modelName => $data) { $count = $data['count']; $totalRecords += $count; $tableData[] = [ 'Model' => $modelName, 'Records' => number_format($count), 'Table' => Str::snake(Str::plural($modelName)) ]; } table(headers: ['Model', 'Records', 'Table'], rows: $tableData); info(''); info("Total Records: " . number_format($totalRecords)); info("Realism Level: " . ucfirst($this->config['options']['realism'] ?? 'medium')); if (!empty($this->config['options']['special_cases'])) { info("Special Cases: " . count($this->config['options']['special_cases']) . " enabled"); } $estimatedTime = max(1, (int)ceil($totalRecords / 100)); info("Estimated Time: ~{$estimatedTime} seconds"); info('═══════════════════════════════════════════════════'); info(''); } private function showPresetSummary(): void { info(''); info('📋 Preset Configuration:'); if (isset($this->config['models'])) { $tableData = []; foreach ($this->config['models'] as $modelName => $data) { $tableData[] = [ 'Model' => $modelName, 'Records' => number_format($data['count']) ]; } table(headers: ['Model', 'Records'], rows: $tableData); } info(''); } private function confirmExecution(): bool { return confirm( label: 'Proceed with seeding?', default: true, yes: 'Yes, start seeding', no: 'Cancel' ); } private function executeSeed(): void { info('🚀 Starting database seeding...'); info(''); if (($this->config['options']['existing_data'] ?? '') === 'truncate') { spin( callback: function () { foreach ($this->config['models'] as $modelName => $data) { $tableName = Str::snake(Str::plural($modelName)); if (Schema::hasTable($tableName)) { DB::table($tableName)->truncate(); } } }, message: 'Truncating tables...' ); info('✅ Tables truncated'); } foreach ($this->config['models'] as $modelName => $data) { $count = $data['count']; $class = $data['class']; if (!class_exists($class)) { warning("⚠️ Model {$class} not found. Skipping."); continue; } $this->seedModel($modelName, $class, $count); } info(''); info('✅ Database seeded successfully!'); info(''); } private function seedModel(string $modelName, string $class, int $count): void { $startTime = microtime(true); try { spin( callback: fn() => $class::factory($count)->create(), message: "Seeding {$modelName}..." ); $duration = round(microtime(true) - $startTime, 2); info("✅ Created {$count} {$modelName} records ({$duration}s)"); } catch (\Exception $e) { error("Failed to seed {$modelName}: {$e->getMessage()}"); if (!confirm("Continue seeding other models?", default: true)) { throw $e; } } } private function offerToSave(): void { info(''); if (confirm('Save this configuration as a preset?', default: false)) { $presetName = text( label: 'Preset name', placeholder: 'e.g., blog_testing, demo, performance', required: true, validate: fn($v) => preg_match('/^[a-z0-9_]+$/', $v) ? null : 'Use lowercase letters, numbers, and underscores only' ); $this->savePreset($presetName); info("✅ Configuration saved as preset: {$presetName}"); info("💡 Run again with: php artisan seed:generate --preset={$presetName}"); } } private function savePreset(string $name): void { $presetsPath = storage_path('app/seeder-presets'); if (!is_dir($presetsPath)) { mkdir($presetsPath, 0755, true); } file_put_contents( "{$presetsPath}/{$name}.json", json_encode($this->config, JSON_PRETTY_PRINT) ); } private function loadPreset(string $name): bool { $filePath = storage_path("app/seeder-presets/{$name}.json"); if (!file_exists($filePath)) { return false; } $this->config = json_decode(file_get_contents($filePath), true); return true; } private function getDefaultCount(string $modelName): string { return match($modelName) { 'User' => '50', 'Post' => '200', 'Comment' => '500', 'Category' => '10', 'Product' => '100', 'Order' => '300', 'Tag' => '20', default => '50' }; } private function getCountHint(string $modelName): string { return match($modelName) { 'User' => 'Recommended: 10-100 for testing', 'Post' => 'Recommended: 50-500 depending on use case', 'Comment' => 'Typically 2-5x the number of posts', 'Category' => 'Usually 5-20 categories', default => 'Enter desired count' }; } } // Load preset if specified // Step 1: Model Selection // Step 2: Configure Counts // Step 3: Configure Relationships // Step 4: Data Quality & Special Options // Step 5: Handle Existing Data // Step 6: Show Summary // Step 7: Confirm and Execute // Convert keys to actual class paths // Check for relationship dependencies Tämä taikuri osoittaa useita tehokkaita ominaisuuksia: Mallin valinta riippuvuustarkistuksella - Sisältää automaattisesti vaaditut mallit (esim. Kommentit vaativat viestejä) Älykäs validointi inline-virhesanomilla - Varmistaa kelvolliset numeeriset syöttöt ja oikeat alueet Suhteiden ehdolliset kehotukset - Kysyy vain asiaankuuluvia kysymyksiä valittujen mallien perusteella Konfiguraation esikatselu taulukoilla - Näyttää puhtaan yhteenvedon ennen suorittamista Esitä järjestelmä - Tallenna konfiguraatiot uudelleenkäyttöä varten eri ympäristöissä Edistymisen palaute kierroksilla - Visuaalinen indikaatio pitkien siementoimintojen aikana Virheiden palauttaminen - käsittelee epäonnistumisia ja mahdollistaa jatkamisen muiden mallien kanssa. Esimerkkejä käytöstä: php artisan seed:generate php artisan seed:generate --preset=blog_testing # Interactive mode - walks through all options # Quick start with preset # Common presets to create: # - blog_testing: 50 users, 200 posts, 400 comments # - demo: Beautiful data for client presentations # - performance: 10,000+ records for load testing # - minimal: Just enough data to start development Tämä lähestymistapa muuttaa tietokannan kylvämisen manuaalisesta, virheille alttiista prosessista opastetuksi kokemukseksi, joka säästää aikaa ja vähentää virheitä. Terminaalikuvat viittaukseksi: on on on on on on on on Mielenkiintoisia faktoja Cross-Platform Compatibility Magic: Laravel Prompts havaitsee automaattisesti terminaaliympäristön ja säätää sen toistostrategiaa. Windowsissa se käyttää erilaisia ohjausjaksoja kuin Unix-pohjaisissa järjestelmissä, mikä takaa yhtenäisen ulkonäön kaikkialla. Zero Dependencies -filosofia: Toisin kuin useimmat CLI-paketit, jotka luottavat ulkoisiin kirjastoihin, Laravel Prompts on täysin itsenäinen. Käytettävyysominaisuudet: Paketti sisältää näytönlukuohjelman tuen ja toimii erilaisten päätelaitteiden saavutettavuustyökalujen kanssa. Näppäimistön navigointi noudattaa tavanomaisia yleissopimuksia, joten käyttäjät tuntevat päätelaitteiden sovellukset intuitiivisesti. Vim Keybinding -tuki: Voimakäyttäjät voivat navigoida kehottimia käyttämällä h, j, k, l-näppäimiä sekä nuolinäppäimiä. Fallback-tila: Kun käytät ympäristöjä, joissa ei ole TTY-tukea (kuten CI / CD-putket), Prompts palaa automaattisesti yksinkertaiseen syöttöön / ulostuloon, varmistaen, että komennot toimivat kaikkialla. parhaita käytäntöjä Tarjoa aina selkeitä, lyhyitä merkintöjä, joissa selitetään, mitä tietoja pyydät. Vältä teknistä jargonia, ellet yleisö odota sitä. Käytä varhaista vahvistusta ja anna hyödyllisiä virheilmoituksia. ”Vieläpäinen syöttö” -viestin sijaan kerro käyttäjille tarkalleen, mikä meni pieleen: ”Portin on oltava numero välillä 1 ja 65535.” Tämä ohje estää turhautumisen ja vähentää tukipyyntöjä. Toteuta kohtuulliset oletusasetukset jokaiselle kehotukselle aina, kun se on mahdollista. Useimmat käyttäjät haluavat vakioasetuksen, joten anna niiden painaa Enter-painiketta hyväksyäksesi oletusasetukset. Ryhmään liittyvät kehotukset kootaan yhteen ja tiedot / varoitusviestit toimitetaan kontekstissa. Monimutkaisten kokoonpanojen rikkominen loogisiin osiin tekee prosessista hallittavan pikemminkin kuin ylivoimaisen. Vaikka Laravel Prompts käsittelee useimpia yhteensopivuusongelmia, kokemuksen tarkistaminen Windows Command Prompt, PowerShell ja erilaiset Unix-kuoret takaavat laadun. Taylor Otwell, Laravelin luoja "Laravel Prompts muuttaa CLI-sovellukset pelottavista mustista laatikoista opastetuiksi, käyttäjäystävällisiksi kokemuksiksi. ja FAQ K: Voinko käyttää Laravel Promptsia Laravel-sovellusten ulkopuolella? V: Kyllä! Laravel Prompts on kehysagnostinen ja toimii missä tahansa PHP-hankkeessa. K: Miten käsittelen kehotuksia automaattisessa testauksessa? A: Laravel Prompts sisältää testausavustajia. Käytä testissä Prompt::fake() -menetelmää simuloidaksesi käyttäjän syöttöä ilman todellista terminaalin vuorovaikutusta. Kysymys: Toimivatko pyynnöt Docker-säiliöissä? V: Kyllä, mutta varmista, että säiliölläsi on TTY käytössä. Käytä docker run -it tai set tty: true docker-compose.yml:ssä, jotta vuorovaikutteiset pyynnöt toimisivat oikein. K: Voinko räätälöidä kehotusten ulkonäköä? A: Vaikka oletusarvoinen muotoilu on johdonmukainen ja ammattimainen, voit luoda mukautettuja kehotuskursseja, jotka laajentavat peruskomponentteja, jos tarvitset tiettyjä visuaalisia muutoksia. K: Mitä tapahtuu, jos käyttäjä peruuttaa kehotuksen Ctrl+C:llä? A: Laravel Prompts kunnioittaa peruuttamista ja heittää UserCancelledException -viestin. K: Ovatko kehotukset yhteensopivia Windows Command Promptin kanssa? A: Ehdottomasti. Laravel Prompts sisältää Windows-ympäristöihin sovellettavan erityisen muokkauslogian, joka varmistaa, että kehotukset näyttävät hyvältä Command Promptissa, PowerShellissä ja Windows-terminaalissa. K: Voinko käyttää tiedostojen valintapyyntöjä? A: Vaikka ei ole sisäänrakennettuja tiedostojen selaimen pyyntöjä, voit yhdistää hakupyyntöjä tiedostojärjestelmän skannaukseen luodaksesi tehokkaita tiedostojen valinta rajapintoja. Kysymys: Miten voin lisätä aputekstiä tai vihjeitä kehotuksiin? V: Useimmat kehotustoiminnot hyväksyvät vihjeparametrin, jossa voit antaa lisäkontekstiä. Freek Van der Herten, Laravelin kehittäjä "Laravel Promptsin todellinen voima ei ole web-lomakkeiden korvaamisessa - se on CLI-työkalujen saavuttamisessa kehittäjille, jotka aiemmin löysivät päätelaitteiden sovellukset pelottaviksi." Johtopäätös Laravel Prompts edustaa merkittävää askelta eteenpäin komentosarjan käyttöliittymän suunnittelussa. Tarjoamalla kauniita, intuitiivisia vuorovaikutuksia nollakokoonpanolla, se poistaa tekniset esteet, jotka kerran tekivät CLI-kehityksestä haastavan. Rakentamamme SMTP-määritysoppaat osoittavat, miten monimutkaiset asennusprosessit voivat muuttua opastetuiksi kokemuksiksi. Sen sijaan, että käyttäjät muokkaisivat konfiguraatiotiedostoja manuaalisesti tai muistaisivat epäselviä asetuksia, voit käydä läpi jokaisen vaiheen validoinnin ja hyödyllisten vihjeiden avulla. Tämä lähestymistapa vähentää virheitä, parantaa käyttäjän tyytyväisyyttä ja tekee sovelluksistasi ammattimaisempia. Kun Laravel 12 kehittyy edelleen, Prompts pysyy ekosysteemin CLI-kehityksen kulmakivenä. Olitpa rakentamassa asennusoppaita, käyttöönottotyökaluja tai interaktiivisia ylläpito-komentoja, Laravel Prompts tarjoaa perustan sellaisten päätelaitteiden luomiselle, joita käyttäjät todella nauttivat.