From 2bd05c82936e4a9ae728c2844dac7af20a116fd1 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Sun, 13 Jul 2025 14:28:56 +0300 Subject: [PATCH 01/12] refactor: use AppTypeEnum --- .../views/clerk_user_repository.blade.php | 20 +++++++++ src/Commands/InitCommand.php | 44 ++++++++++++++----- src/Enums/AppTypeEnum.php | 14 ++++++ 3 files changed, 66 insertions(+), 12 deletions(-) create mode 100644 resources/views/clerk_user_repository.blade.php create mode 100644 src/Enums/AppTypeEnum.php diff --git a/resources/views/clerk_user_repository.blade.php b/resources/views/clerk_user_repository.blade.php new file mode 100644 index 0000000..4e8954f --- /dev/null +++ b/resources/views/clerk_user_repository.blade.php @@ -0,0 +1,20 @@ +namespace App\Support\Clerk; + +use App\Models\Role; +use App\Models\User; +use Lcobucci\JWT\Token; +use RonasIT\Clerk\Repositories\UserRepository; + +class ClerkUserRepository extends UserRepository +{ + public function fromToken(Token $token): User + { + $user = parent::fromToken($token); + + return User::firstOrCreate([ + 'clerk_id' => $user->getAuthIdentifier(), + ], [ + 'role_id' => Role::USER, + ]); + } +} \ No newline at end of file diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index e3c3ea9..24b7302 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -12,7 +12,7 @@ use Illuminate\Support\Str; use RonasIT\ProjectInitializator\Enums\AuthTypeEnum; use RonasIT\ProjectInitializator\Enums\RoleEnum; -use Winter\LaravelConfigWriter\ArrayFile; +use RonasIT\ProjectInitializator\Enums\AppTypeEnum; class InitCommand extends Command implements Isolatable { @@ -69,6 +69,10 @@ class InitCommand extends Command implements Isolatable protected string $appName; + protected ?string $reviewer = null; + + protected AppTypeEnum $appType; + public function handle(): void { $this->prepareAppName(); @@ -80,7 +84,7 @@ public function handle(): void field: 'email of code owner / team lead', rules: 'required|email', ); - + $this->appUrl = $this->ask('Please enter an application URL', "https://api.dev.{$kebabName}.com"); $envFile = (file_exists('.env')) ? '.env' : '.env.example'; @@ -96,6 +100,14 @@ public function handle(): void $this->info('Project initialized successfully!'); + $this->appType = AppTypeEnum::from( + $this->choice( + question: 'What type of application will your API serve?', + choices: AppTypeEnum::values(), + default: AppTypeEnum::Multiplatform->value + ) + ); + $this->authType = AuthTypeEnum::from($this->choice( question: 'Please choose the authentication type', choices: AuthTypeEnum::values(), @@ -112,6 +124,20 @@ public function handle(): void $this->createOrUpdateConfigFile($envFile, '=', [ 'AUTH_GUARD' => 'clerk', ]); + + $data = [ + 'CLERK_ALLOWED_ISSUER' => '', + 'CLERK_SECRET_KEY' => '', + 'CLERK_SIGNER_KEY_PATH' => '', + ]; + + if ($this->appType !== AppTypeEnum::Mobile) { + $data['CLERK_ALLOWED_ORIGINS'] = ''; + } + + $this->createOrUpdateConfigFile($envFile, '=', $data); + $this->createOrUpdateConfigFile('.env.development', '=', $data); + $this->createOrUpdateConfigFile('.env.example', '=', $data); } if ($this->confirm('Do you want to generate an admin user?', true)) { @@ -198,7 +224,7 @@ public function handle(): void protected function setAutoDocContactEmail(string $email): void { $config = ArrayFile::open(base_path('config/auto-doc.php')); - + $config->set('info.contact.email', $email); $config->write(); @@ -235,13 +261,7 @@ protected function fillReadme(): void $this->setReadmeValue($file, 'project_name', $this->appName); - $type = $this->choice( - question: 'What type of application will your API serve?', - choices: ['Mobile', 'Web', 'Multiplatform'], - default: 'Multiplatform' - ); - - $this->setReadmeValue($file, 'type', $type); + $this->setReadmeValue($file, 'type', $this->appType->value); $this->readmeContent = $file; } @@ -300,9 +320,9 @@ protected function fillContacts(): void $this->removeTag($filePart, $key); } - + $this->setReadmeValue($filePart, 'team_lead_link', $this->codeOwnerEmail); - + $this->updateReadmeFile($filePart); } diff --git a/src/Enums/AppTypeEnum.php b/src/Enums/AppTypeEnum.php new file mode 100644 index 0000000..e92872b --- /dev/null +++ b/src/Enums/AppTypeEnum.php @@ -0,0 +1,14 @@ + Date: Thu, 21 Aug 2025 17:30:41 +0300 Subject: [PATCH 02/12] feat: add app type enum --- src/Commands/InitCommand.php | 16 +- src/Enums/AppTypeEnum.php | 6 +- tests/InitCommandTest.php | 229 +++++++++++++++++- .../default_readme_with_mobile_app.md | 85 +++++++ ...me_with_mobile_app_after_using_renovate.md | 89 +++++++ ...nv.development_clerk_credentials_added.yml | 44 ++++ ...ent_clerk_credentials_added_mobile_app.yml | 43 ++++ .../env.example_clerk_credentials_added.yml | 47 ++++ ...ple_clerk_credentials_added_mobile_app.yml | 46 ++++ 9 files changed, 596 insertions(+), 9 deletions(-) create mode 100644 tests/fixtures/InitCommandTest/default_readme_with_mobile_app.md create mode 100644 tests/fixtures/InitCommandTest/default_readme_with_mobile_app_after_using_renovate.md create mode 100644 tests/fixtures/InitCommandTest/env.development_clerk_credentials_added.yml create mode 100644 tests/fixtures/InitCommandTest/env.development_clerk_credentials_added_mobile_app.yml create mode 100644 tests/fixtures/InitCommandTest/env.example_clerk_credentials_added.yml create mode 100644 tests/fixtures/InitCommandTest/env.example_clerk_credentials_added_mobile_app.yml diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index 24b7302..e4d6f6b 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -13,6 +13,7 @@ use RonasIT\ProjectInitializator\Enums\AuthTypeEnum; use RonasIT\ProjectInitializator\Enums\RoleEnum; use RonasIT\ProjectInitializator\Enums\AppTypeEnum; +use Winter\LaravelConfigWriter\ArrayFile; class InitCommand extends Command implements Isolatable { @@ -137,7 +138,10 @@ public function handle(): void $this->createOrUpdateConfigFile($envFile, '=', $data); $this->createOrUpdateConfigFile('.env.development', '=', $data); - $this->createOrUpdateConfigFile('.env.example', '=', $data); + + if ($envFile !== '.env.example') { + $this->createOrUpdateConfigFile('.env.example', '=', $data); + } } if ($this->confirm('Do you want to generate an admin user?', true)) { @@ -418,6 +422,8 @@ protected function createOrUpdateConfigFile(string $fileName, string $separator, $lines = explode("\n", $parsed); + $previousKey = null; + foreach ($data as $key => $value) { $value = $this->addQuotes($value); @@ -429,7 +435,13 @@ protected function createOrUpdateConfigFile(string $fileName, string $separator, } } - $lines[] = "\n{$key}{$separator}{$value}"; + if (Str::before($key, '_') === Str::before($previousKey, '_')) { + $lines[] = "{$key}{$separator}{$value}"; + } else { + $lines[] = "\n{$key}{$separator}{$value}"; + } + + $previousKey = $key; } $ymlSettings = implode("\n", $lines); diff --git a/src/Enums/AppTypeEnum.php b/src/Enums/AppTypeEnum.php index e92872b..9532078 100644 --- a/src/Enums/AppTypeEnum.php +++ b/src/Enums/AppTypeEnum.php @@ -8,7 +8,7 @@ enum AppTypeEnum: string { use EnumTrait; - case Mobile = 'mobile'; - case Web = 'web'; - case Multiplatform = 'multiplatform'; + case Mobile = 'Mobile'; + case Web = 'Web'; + case Multiplatform = 'Multiplatform'; } diff --git a/tests/InitCommandTest.php b/tests/InitCommandTest.php index 2f50b91..eb0b5f7 100644 --- a/tests/InitCommandTest.php +++ b/tests/InitCommandTest.php @@ -45,6 +45,7 @@ public function testRunWithoutAdminAndReadmeCreationConvertAppNameToPascalCaseTe ->expectsQuestion("Please specify a Code Owner/Team Lead's email", 'test@example.com') ->expectsOutput('Project initialized successfully!') ->expectsQuestion('Please enter an application URL', 'https://mysite.com') + ->expectsQuestion('What type of application will your API serve?', 'Multiplatform') ->expectsChoice('Please choose the authentication type', 'none', ['clerk', 'none']) ->expectsConfirmation('Do you want to generate an admin user?') ->expectsConfirmation('Do you want to generate a README file?') @@ -92,6 +93,7 @@ public function testRunWithoutAdminAndReadmeCreation() ->expectsQuestion("Please specify a Code Owner/Team Lead's email", 'test@example.com') ->expectsOutput('Project initialized successfully!') ->expectsQuestion('Please enter an application URL', 'https://mysite.com') + ->expectsQuestion('What type of application will your API serve?', 'Multiplatform') ->expectsChoice('Please choose the authentication type', 'none', ['clerk', 'none']) ->expectsConfirmation('Do you want to generate an admin user?') ->expectsConfirmation('Do you want to generate a README file?') @@ -141,6 +143,7 @@ public function testRunWithAdminAndWithoutReadmeCreation() ->expectsQuestion("Please specify a Code Owner/Team Lead's email", 'test@example.com') ->expectsOutput('Project initialized successfully!') ->expectsQuestion('Please enter an application URL', 'https://mysite.com') + ->expectsQuestion('What type of application will your API serve?', 'Multiplatform') ->expectsChoice('Please choose the authentication type', 'none', ['clerk', 'none']) ->expectsConfirmation('Do you want to generate an admin user?', 'yes') ->expectsQuestion('Please enter an admin email', 'mail@mail.com') @@ -179,6 +182,14 @@ public function testRunWithAdminAndDefaultReadmeCreation() 'arguments' => ['.env.example'], 'result' => $this->getFixture('env.example.yml'), ], + [ + 'arguments' => ['.env.example'], + 'result' => $this->getFixture('env.example.yml'), + ], + [ + 'arguments' => ['.env.development'], + 'result' => $this->getFixture('env.development.yml'), + ], [ 'arguments' => [base_path('/vendor/ronasit/laravel-project-initializator/resources/md/readme/README.md')], 'result' => $this->getTemplate('README.md'), @@ -240,6 +251,14 @@ public function testRunWithAdminAndDefaultReadmeCreation() '.env.example', $this->getFixture('env.example_clerk_guard_added.yml'), ], + [ + '.env.example', + $this->getFixture('env.example_clerk_credentials_added.yml'), + ], + [ + '.env.development', + $this->getFixture('env.development_clerk_credentials_added.yml'), + ], [ 'database/migrations/2018_11_11_111111_admins_create_table.php', $this->getFixture('admins_table_migration.php'), @@ -276,12 +295,12 @@ public function testRunWithAdminAndDefaultReadmeCreation() ->expectsQuestion("Please specify a Code Owner/Team Lead's email", 'test@example.com') ->expectsOutput('Project initialized successfully!') ->expectsQuestion('Please enter an application URL', 'https://mysite.com') + ->expectsQuestion('What type of application will your API serve?', 'Multiplatform') ->expectsChoice('Please choose the authentication type', 'clerk', ['clerk', 'none']) ->expectsConfirmation('Do you want to generate an admin user?', 'yes') ->expectsQuestion('Please enter an admin email', 'mail@mail.com') ->expectsQuestion('Please enter an admin password', '123456') ->expectsConfirmation('Do you want to generate a README file?', 'yes') - ->expectsQuestion('What type of application will your API serve?', 'Multiplatform') ->expectsConfirmation('Do you need a `Resources & Contacts` part?', 'yes') ->expectsQuestion( 'Are you going to use Issue Tracker? ' @@ -403,10 +422,10 @@ public function testRunWithAdminAndPartialReadmeCreation() ->expectsQuestion("Please specify a Code Owner/Team Lead's email", 'test@example.com') ->expectsOutput('Project initialized successfully!') ->expectsQuestion('Please enter an application URL', 'https://mysite.com') + ->expectsQuestion('What type of application will your API serve?', 'Web') ->expectsChoice('Please choose the authentication type', 'none', ['clerk', 'none']) ->expectsConfirmation('Do you want to generate an admin user?') ->expectsConfirmation('Do you want to generate a README file?', 'yes') - ->expectsQuestion('What type of application will your API serve?', 'Web') ->expectsConfirmation('Do you need a `Resources & Contacts` part?', 'yes') ->expectsQuestion( 'Are you going to use Issue Tracker? ' @@ -547,6 +566,7 @@ public function testRunWithAdminAndFullReadmeCreationAndRemovingInitializatorIns ->expectsQuestion("Please specify a Code Owner/Team Lead's email", 'test@example.com') ->expectsOutput('Project initialized successfully!') ->expectsQuestion('Please enter an application URL', 'https://mysite.com') + ->expectsQuestion('What type of application will your API serve?', 'Mobile') ->expectsChoice('Please choose the authentication type', 'none', ['clerk', 'none']) ->expectsConfirmation('Do you want to generate an admin user?', 'yes') ->expectsQuestion('Please enter an admin email', 'mail@mail.com') @@ -554,7 +574,6 @@ public function testRunWithAdminAndFullReadmeCreationAndRemovingInitializatorIns ->expectsQuestion('Please enter an admin name', 'TestAdmin') ->expectsQuestion('Please enter an admin role id', 1) ->expectsConfirmation('Do you want to generate a README file?', 'yes') - ->expectsQuestion('What type of application will your API serve?', 'Mobile') ->expectsConfirmation('Do you need a `Resources & Contacts` part?', 'yes') ->expectsQuestion( 'Are you going to use Issue Tracker? ' @@ -671,10 +690,10 @@ public function testRunWithoutAdminAndUsingTelescope() ->expectsQuestion("Please specify a Code Owner/Team Lead's email", 'test@example.com') ->expectsOutput('Project initialized successfully!') ->expectsQuestion('Please enter an application URL', 'https://mysite.com') + ->expectsQuestion('What type of application will your API serve?', 'Web') ->expectsChoice('Please choose the authentication type', 'none', ['clerk', 'none']) ->expectsConfirmation('Do you want to generate an admin user?') ->expectsConfirmation('Do you want to generate a README file?', 'yes') - ->expectsQuestion('What type of application will your API serve?', 'Web') ->expectsConfirmation('Do you need a `Resources & Contacts` part?', 'yes') ->expectsQuestion( 'Are you going to use Issue Tracker? ' @@ -728,4 +747,206 @@ public function testRunWithoutAdminAndUsingTelescope() ->expectsConfirmation('Do you want to uninstall project-initializator package?') ->assertExitCode(0); } + + public function testRunWithClerkMobileApp(): void + { + $this->mockChangeConfig('config/auto-doc.php', 'auto_doc.php', 'auto_doc_after_changes.php'); + + $this->mockFileGetContent( + [ + 'arguments' => ['.env.example'], + 'result' => $this->getFixture('env.example.yml'), + ], + [ + 'arguments' => ['.env.development'], + 'result' => $this->getFixture('env.development.yml'), + ], + [ + 'arguments' => ['config/auth.php'], + 'result' => $this->getFixture('auth.php'), + ], + [ + 'arguments' => ['.env.development'], + 'result' => $this->getFixture('env.development.yml'), + ], + [ + 'arguments' => ['.env.example'], + 'result' => $this->getFixture('env.example.yml'), + ], + [ + 'arguments' => ['.env.example'], + 'result' => $this->getFixture('env.example.yml'), + ], + [ + 'arguments' => ['.env.development'], + 'result' => $this->getFixture('env.development.yml'), + ], + [ + 'arguments' => [base_path('/vendor/ronasit/laravel-project-initializator/resources/md/readme/README.md')], + 'result' => $this->getTemplate('README.md'), + ], + [ + 'arguments' => [base_path('/vendor/ronasit/laravel-project-initializator/resources/md/readme/RESOURCES_AND_CONTACTS.md')], + 'result' => $this->getTemplate('RESOURCES_AND_CONTACTS.md'), + ], + [ + 'arguments' => [base_path('/vendor/ronasit/laravel-project-initializator/resources/md/readme/RESOURCES.md')], + 'result' => $this->getTemplate('RESOURCES.md'), + ], + [ + 'arguments' => [base_path('/vendor/ronasit/laravel-project-initializator/resources/md/readme/CONTACTS.md')], + 'result' => $this->getTemplate('CONTACTS.md'), + ], + [ + 'arguments' => [base_path('/vendor/ronasit/laravel-project-initializator/resources/md/readme/PREREQUISITES.md')], + 'result' => $this->getTemplate('PREREQUISITES.md'), + ], + [ + 'arguments' => [base_path('/vendor/ronasit/laravel-project-initializator/resources/md/readme/GETTING_STARTED.md')], + 'result' => $this->getTemplate('GETTING_STARTED.md'), + ], + [ + 'arguments' => [base_path('/vendor/ronasit/laravel-project-initializator/resources/md/readme/ENVIRONMENTS.md')], + 'result' => $this->getTemplate('ENVIRONMENTS.md'), + ], + [ + 'arguments' => [base_path('/vendor/ronasit/laravel-project-initializator/resources/md/readme/CREDENTIALS_AND_ACCESS.md')], + 'result' => $this->getTemplate('CREDENTIALS_AND_ACCESS.md'), + ], + [ + 'arguments' => [base_path('/vendor/ronasit/laravel-project-initializator/resources/md/readme/CLERK.md')], + 'result' => $this->getTemplate('CLERK.md'), + ], + [ + 'arguments' => [base_path('/vendor/ronasit/laravel-project-initializator/resources/md/readme/RENOVATE.md')], + 'result' => $this->getTemplate('RENOVATE.md'), + ], + ); + + $this->mockFilePutContent( + 'env.example.yml', + 'env.development.yml', + [ + 'config/auth.php', + $this->getFixture('auth-modified.php'), + ], + [ + 'database/migrations/2018_11_11_111111_users_add_clerk_id_field.php', + $this->getFixture('users_add_clerk_id_field_migration.php'), + ], + [ + '.env.development', + $this->getFixture('env.development_clerk_guard_added.yml'), + ], + [ + '.env.example', + $this->getFixture('env.example_clerk_guard_added.yml'), + ], + [ + '.env.example', + $this->getFixture('env.example_clerk_credentials_added_mobile_app.yml'), + ], + [ + '.env.development', + $this->getFixture('env.development_clerk_credentials_added_mobile_app.yml'), + ], + [ + 'database/migrations/2018_11_11_111111_admins_create_table.php', + $this->getFixture('admins_table_migration.php'), + ], + [ + 'README.md', + $this->getFixture('default_readme_with_mobile_app.md'), + ], + [ + 'renovate.json', + $this->getFixture('renovate.json'), + ], + [ + 'README.md', + $this->getFixture('default_readme_with_mobile_app_after_using_renovate.md'), + ], + ); + + $this->mockShellExec( + ['arguments' => 'git ls-remote --get-url origin', 'result' => 'https://github.com/ronasit/laravel-helpers.git'], + ['arguments' => 'composer require ronasit/laravel-helpers --ansi'], + ['arguments' => 'composer require ronasit/laravel-swagger --ansi'], + ['arguments' => 'php artisan vendor:publish --provider="RonasIT\AutoDoc\AutoDocServiceProvider" --ansi'], + ['arguments' => 'composer require --dev ronasit/laravel-entity-generator --ansi'], + ['arguments' => 'composer require ronasit/laravel-clerk --ansi'], + ['arguments' => 'php artisan vendor:publish --provider="RonasIT\\Clerk\\Providers\\ClerkServiceProvider" --ansi'], + ['arguments' => 'composer require ronasit/laravel-telescope-extension --ansi'], + ['arguments' => 'php artisan telescope:install --ansi'], + ); + + $this + ->artisan('init "My App"') + ->expectsConfirmation('The application name is not in PascalCase, would you like to use MyApp') + ->expectsQuestion("Please specify a Code Owner/Team Lead's email", 'test@example.com') + ->expectsOutput('Project initialized successfully!') + ->expectsQuestion('Please enter an application URL', 'https://mysite.com') + ->expectsQuestion('What type of application will your API serve?', 'Mobile') + ->expectsChoice('Please choose the authentication type', 'clerk', ['clerk', 'none']) + ->expectsConfirmation('Do you want to generate an admin user?', 'yes') + ->expectsQuestion('Please enter an admin email', 'mail@mail.com') + ->expectsQuestion('Please enter an admin password', '123456') + ->expectsConfirmation('Do you want to generate a README file?', 'yes') + ->expectsConfirmation('Do you need a `Resources & Contacts` part?', 'yes') + ->expectsQuestion( + 'Are you going to use Issue Tracker? ' + . 'Please enter a link or select `later` to do it later, otherwise select `no`.', + 'later' + ) + ->expectsQuestion( + 'Are you going to use Figma? ' + . 'Please enter a link or select `later` to do it later, otherwise select `no`.', + 'later' + ) + ->expectsQuestion( + 'Are you going to use Sentry? ' + . 'Please enter a link or select `later` to do it later, otherwise select `no`.', + 'later' + ) + ->expectsQuestion( + 'Are you going to use DataDog? ' + . 'Please enter a link or select `later` to do it later, otherwise select `no`.', + 'later' + ) + ->expectsQuestion( + 'Are you going to use ArgoCD? ' + . 'Please enter a link or select `later` to do it later, otherwise select `no`.', + 'later' + ) + ->expectsQuestion( + 'Are you going to use Laravel Telescope? ' + . 'Please enter a link or select `later` to do it later, otherwise select `no`.', + 'later' + ) + ->expectsQuestion( + 'Are you going to use Laravel Nova? ' + . 'Please enter a link or select `later` to do it later, otherwise select `no`.', + 'later' + ) + ->expectsQuestion('Please enter a Manager\'s email', '') + ->expectsConfirmation('Do you need a `Prerequisites` part?', 'yes') + ->expectsConfirmation('Do you need a `Getting Started` part?', 'yes') + ->expectsConfirmation('Do you need an `Environments` part?', 'yes') + ->expectsConfirmation('Do you need a `Credentials and Access` part?', 'yes') + ->expectsConfirmation('Is Laravel Telescope\'s admin the same as default one?', 'yes') + ->expectsConfirmation('Is Laravel Nova\'s admin the same as default one?', 'yes') + ->expectsOutput('README generated successfully!') + ->expectsOutput('Don`t forget to fill the following empty values:') + ->expectsOutput('- Issue Tracker link') + ->expectsOutput('- Figma link') + ->expectsOutput('- Sentry link') + ->expectsOutput('- DataDog link') + ->expectsOutput('- ArgoCD link') + ->expectsOutput('- Manager\'s email') + ->expectsConfirmation('Would you use Renovate dependabot?', 'yes') + ->expectsQuestion('Please type username of the project reviewer', 'reviewer') + ->expectsConfirmation('Do you want to install media package?') + ->expectsConfirmation('Do you want to uninstall project-initializator package?') + ->assertExitCode(0); + } } diff --git a/tests/fixtures/InitCommandTest/default_readme_with_mobile_app.md b/tests/fixtures/InitCommandTest/default_readme_with_mobile_app.md new file mode 100644 index 0000000..2d6e6c7 --- /dev/null +++ b/tests/fixtures/InitCommandTest/default_readme_with_mobile_app.md @@ -0,0 +1,85 @@ +# My App + +This project implements an API for the My App Mobile app. + +## Project Resources & Contacts + +This section provides quick links to various resources and contacts associated +with this project. It's here to streamline your navigation and communication +process, so you can efficiently find what you need or reach out to who you need. + +### Resources + +Below are links to tools and services used in this project: +- [Issue Tracker](): Here, you can report any issues or bugs related to the project. (will be added later) +- [Figma](): This is where we maintain all our design assets and mock-ups. (will be added later) +- [Sentry](): To monitor application performance and error tracking. (will be added later) +- [DataDog](): This is where we monitor our logs, and server performance, and receive alerts. (will be added later) +- [ArgoCD](): Is a kubernetes controller which continuously monitors running applications. (will be added later) +- [Laravel Telescope](): This is debug assistant for the Laravel framework. (will be added later) +- [Laravel Nova](): This is admin panel for the Laravel framework. (will be added later) +- [API Documentation](https://mysite.com) + +### Contacts + +Should you need assistance or have questions, feel free to connect with the following individuals: +- Manager: If you have any high-level project concerns, feel free to get in touch with our project manager. [Connect with Manager](mailto::manager_link) +- Code Owner/Team Lead: For specific questions about the codebase or technical aspects, reach out to our team lead. [Connect with Team Lead](mailto:test@example.com) + +Please be mindful of each individual's preferred contact method and office hours. + +## Prerequisites + +To work with this repository, you will need to have the following +installed: + +- [Docker](https://www.docker.com) + +## Getting Started + +To get started with this repository, follow these steps: + +Clone this repository to your local machine: + +```sh +git clone https://github.com/ronasit/laravel-helpers.git +``` + +Open project directory: + +```sh +cd laravel-helpers +``` + +Build and start containers, it may takes some time: + +```sh +docker compose up -d +``` + +## Environments + +This repository by default supports three environments: `local`, `development`, +and `testing`. Each environment is represented by an appropriate environment file: + +| Environment | File | URL | +| --- | --- |--------------------------------------| +| local | .env | [http://localhost](http://localhost) | +| testing | .env.testing | - | +| development | .env.development | [https://mysite.com](https://mysite.com) | + +## Credentials and Access + +Default admin access: +- email `mail@mail.com` +- password `123456` + +Laravel Telescope access: +- email `mail@mail.com` +- password `123456` + +Laravel Nova access: +- email `mail@mail.com` +- password `123456` + +Core auth solution is [Clerk](https://clerk.com) so in `development` environment use any test phones and emails from [this list](https://clerk.com/docs/testing/test-emails-and-phones) diff --git a/tests/fixtures/InitCommandTest/default_readme_with_mobile_app_after_using_renovate.md b/tests/fixtures/InitCommandTest/default_readme_with_mobile_app_after_using_renovate.md new file mode 100644 index 0000000..a839b3b --- /dev/null +++ b/tests/fixtures/InitCommandTest/default_readme_with_mobile_app_after_using_renovate.md @@ -0,0 +1,89 @@ +# My App + +This project implements an API for the My App Mobile app. + +## Project Resources & Contacts + +This section provides quick links to various resources and contacts associated +with this project. It's here to streamline your navigation and communication +process, so you can efficiently find what you need or reach out to who you need. + +### Resources + +Below are links to tools and services used in this project: +- [Issue Tracker](): Here, you can report any issues or bugs related to the project. (will be added later) +- [Figma](): This is where we maintain all our design assets and mock-ups. (will be added later) +- [Sentry](): To monitor application performance and error tracking. (will be added later) +- [DataDog](): This is where we monitor our logs, and server performance, and receive alerts. (will be added later) +- [ArgoCD](): Is a kubernetes controller which continuously monitors running applications. (will be added later) +- [Laravel Telescope](): This is debug assistant for the Laravel framework. (will be added later) +- [Laravel Nova](): This is admin panel for the Laravel framework. (will be added later) +- [API Documentation](https://mysite.com) + +### Contacts + +Should you need assistance or have questions, feel free to connect with the following individuals: +- Manager: If you have any high-level project concerns, feel free to get in touch with our project manager. [Connect with Manager](mailto::manager_link) +- Code Owner/Team Lead: For specific questions about the codebase or technical aspects, reach out to our team lead. [Connect with Team Lead](mailto:test@example.com) + +Please be mindful of each individual's preferred contact method and office hours. + +## Prerequisites + +To work with this repository, you will need to have the following +installed: + +- [Docker](https://www.docker.com) + +## Getting Started + +To get started with this repository, follow these steps: + +Clone this repository to your local machine: + +```sh +git clone https://github.com/ronasit/laravel-helpers.git +``` + +Open project directory: + +```sh +cd laravel-helpers +``` + +Build and start containers, it may takes some time: + +```sh +docker compose up -d +``` + +## Environments + +This repository by default supports three environments: `local`, `development`, +and `testing`. Each environment is represented by an appropriate environment file: + +| Environment | File | URL | +| --- | --- |--------------------------------------| +| local | .env | [http://localhost](http://localhost) | +| testing | .env.testing | - | +| development | .env.development | [https://mysite.com](https://mysite.com) | + +## Credentials and Access + +Default admin access: +- email `mail@mail.com` +- password `123456` + +Laravel Telescope access: +- email `mail@mail.com` +- password `123456` + +Laravel Nova access: +- email `mail@mail.com` +- password `123456` + +Core auth solution is [Clerk](https://clerk.com) so in `development` environment use any test phones and emails from [this list](https://clerk.com/docs/testing/test-emails-and-phones) + +### Renovate + +The application uses Renovate dependabot for automatically updating dependencies. You can configure it more precisely using the `renovate.json` file. Available configuration described here https://docs.renovatebot.com/config-overview \ No newline at end of file diff --git a/tests/fixtures/InitCommandTest/env.development_clerk_credentials_added.yml b/tests/fixtures/InitCommandTest/env.development_clerk_credentials_added.yml new file mode 100644 index 0000000..12062dc --- /dev/null +++ b/tests/fixtures/InitCommandTest/env.development_clerk_credentials_added.yml @@ -0,0 +1,44 @@ +APP_NAME="My App" +APP_ENV=development +APP_KEY= +APP_DEBUG=true +APP_LOG_LEVEL=debug +APP_URL=https://mysite.com + +DB_CONNECTION=pgsql +DB_HOST= +DB_PORT= +DB_DATABASE= +DB_USERNAME= +DB_PASSWORD= + +BROADCAST_DRIVER=log +CACHE_DRIVER=file +SESSION_DRIVER=redis +QUEUE_CONNECTION=redis + +REDIS_HOST=redis +REDIS_PASSWORD= +REDIS_PORT= + +MAIL_DRIVER=smtp +MAIL_HOST= +MAIL_PORT= +MAIL_USERNAME= +MAIL_PASSWORD= +MAIL_ENCRYPTION= + +FILESYSTEM_DISK=gcs + +PUSHER_APP_ID= +PUSHER_APP_KEY= +PUSHER_APP_SECRET= + +FRONTEND_URL= + +JWT_SHOW_BLACKLIST_EXCEPTION=true + +CLERK_ALLOWED_ISSUER= +CLERK_SECRET_KEY= +CLERK_SIGNER_KEY_PATH= +CLERK_ALLOWED_ORIGINS= \ No newline at end of file diff --git a/tests/fixtures/InitCommandTest/env.development_clerk_credentials_added_mobile_app.yml b/tests/fixtures/InitCommandTest/env.development_clerk_credentials_added_mobile_app.yml new file mode 100644 index 0000000..3baa711 --- /dev/null +++ b/tests/fixtures/InitCommandTest/env.development_clerk_credentials_added_mobile_app.yml @@ -0,0 +1,43 @@ +APP_NAME="My App" +APP_ENV=development +APP_KEY= +APP_DEBUG=true +APP_LOG_LEVEL=debug +APP_URL=https://mysite.com + +DB_CONNECTION=pgsql +DB_HOST= +DB_PORT= +DB_DATABASE= +DB_USERNAME= +DB_PASSWORD= + +BROADCAST_DRIVER=log +CACHE_DRIVER=file +SESSION_DRIVER=redis +QUEUE_CONNECTION=redis + +REDIS_HOST=redis +REDIS_PASSWORD= +REDIS_PORT= + +MAIL_DRIVER=smtp +MAIL_HOST= +MAIL_PORT= +MAIL_USERNAME= +MAIL_PASSWORD= +MAIL_ENCRYPTION= + +FILESYSTEM_DISK=gcs + +PUSHER_APP_ID= +PUSHER_APP_KEY= +PUSHER_APP_SECRET= + +FRONTEND_URL= + +JWT_SHOW_BLACKLIST_EXCEPTION=true + +CLERK_ALLOWED_ISSUER= +CLERK_SECRET_KEY= +CLERK_SIGNER_KEY_PATH= \ No newline at end of file diff --git a/tests/fixtures/InitCommandTest/env.example_clerk_credentials_added.yml b/tests/fixtures/InitCommandTest/env.example_clerk_credentials_added.yml new file mode 100644 index 0000000..7c1a023 --- /dev/null +++ b/tests/fixtures/InitCommandTest/env.example_clerk_credentials_added.yml @@ -0,0 +1,47 @@ +APP_NAME="My App" +APP_ENV=local +APP_KEY= +APP_DEBUG=true +APP_LOG_LEVEL=debug +APP_URL=http://localhost + +DB_CONNECTION=pgsql +DB_HOST=pgsql +DB_PORT=5432 +DB_DATABASE=postgres +DB_USERNAME=postgres +DB_PASSWORD="" + +BROADCAST_DRIVER=log +CACHE_DRIVER=redis +SESSION_DRIVER=redis +QUEUE_CONNECTION=sync + +REDIS_HOST=redis +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_DRIVER=smtp +MAIL_HOST=smtp.mailtrap.io +MAIL_PORT=2525 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null + +FILESYSTEM_DISK=local +GOOGLE_CLOUD_STORAGE_BUCKET=ronasit-development +GOOGLE_CLOUD_PROJECT_ID=ronas-it-development + +PUSHER_APP_ID= +PUSHER_APP_KEY= +PUSHER_APP_SECRET= + +FRONTEND_URL=http://localhost + +JWT_SECRET= +JWT_SHOW_BLACKLIST_EXCEPTION=true + +CLERK_ALLOWED_ISSUER= +CLERK_SECRET_KEY= +CLERK_SIGNER_KEY_PATH= +CLERK_ALLOWED_ORIGINS= \ No newline at end of file diff --git a/tests/fixtures/InitCommandTest/env.example_clerk_credentials_added_mobile_app.yml b/tests/fixtures/InitCommandTest/env.example_clerk_credentials_added_mobile_app.yml new file mode 100644 index 0000000..923f0bf --- /dev/null +++ b/tests/fixtures/InitCommandTest/env.example_clerk_credentials_added_mobile_app.yml @@ -0,0 +1,46 @@ +APP_NAME="My App" +APP_ENV=local +APP_KEY= +APP_DEBUG=true +APP_LOG_LEVEL=debug +APP_URL=http://localhost + +DB_CONNECTION=pgsql +DB_HOST=pgsql +DB_PORT=5432 +DB_DATABASE=postgres +DB_USERNAME=postgres +DB_PASSWORD="" + +BROADCAST_DRIVER=log +CACHE_DRIVER=redis +SESSION_DRIVER=redis +QUEUE_CONNECTION=sync + +REDIS_HOST=redis +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_DRIVER=smtp +MAIL_HOST=smtp.mailtrap.io +MAIL_PORT=2525 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null + +FILESYSTEM_DISK=local +GOOGLE_CLOUD_STORAGE_BUCKET=ronasit-development +GOOGLE_CLOUD_PROJECT_ID=ronas-it-development + +PUSHER_APP_ID= +PUSHER_APP_KEY= +PUSHER_APP_SECRET= + +FRONTEND_URL=http://localhost + +JWT_SECRET= +JWT_SHOW_BLACKLIST_EXCEPTION=true + +CLERK_ALLOWED_ISSUER= +CLERK_SECRET_KEY= +CLERK_SIGNER_KEY_PATH= \ No newline at end of file From 3b9d3edb70a934a405ad1da8fcf2fa078765799e Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Sat, 23 Aug 2025 14:30:29 +0300 Subject: [PATCH 03/12] fix: remove useless --- .../views/clerk_user_repository.blade.php | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 resources/views/clerk_user_repository.blade.php diff --git a/resources/views/clerk_user_repository.blade.php b/resources/views/clerk_user_repository.blade.php deleted file mode 100644 index 4e8954f..0000000 --- a/resources/views/clerk_user_repository.blade.php +++ /dev/null @@ -1,20 +0,0 @@ -namespace App\Support\Clerk; - -use App\Models\Role; -use App\Models\User; -use Lcobucci\JWT\Token; -use RonasIT\Clerk\Repositories\UserRepository; - -class ClerkUserRepository extends UserRepository -{ - public function fromToken(Token $token): User - { - $user = parent::fromToken($token); - - return User::firstOrCreate([ - 'clerk_id' => $user->getAuthIdentifier(), - ], [ - 'role_id' => Role::USER, - ]); - } -} \ No newline at end of file From 0de391be0fb7c6688b69d817a72dbf4b986fbee2 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Sat, 23 Aug 2025 14:31:38 +0300 Subject: [PATCH 04/12] fix:remove useless --- src/Commands/InitCommand.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index e4d6f6b..0b67835 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -69,9 +69,7 @@ class InitCommand extends Command implements Isolatable ]; protected string $appName; - - protected ?string $reviewer = null; - + protected AppTypeEnum $appType; public function handle(): void From 8b496d189f50920222d2ad19ca0641c4fbf7d343 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Sat, 23 Aug 2025 14:37:48 +0300 Subject: [PATCH 05/12] refactor: use variable --- src/Commands/InitCommand.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index 0b67835..9b0e857 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -69,7 +69,7 @@ class InitCommand extends Command implements Isolatable ]; protected string $appName; - + protected AppTypeEnum $appType; public function handle(): void @@ -433,10 +433,12 @@ protected function createOrUpdateConfigFile(string $fileName, string $separator, } } + $item = "{$key}{$separator}{$value}"; + if (Str::before($key, '_') === Str::before($previousKey, '_')) { - $lines[] = "{$key}{$separator}{$value}"; + $lines[] = $item; } else { - $lines[] = "\n{$key}{$separator}{$value}"; + $lines[] = "\n{$item}"; } $previousKey = $key; From a649f9703230b9574fd98b4705c9f270933a1e60 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Mon, 25 Aug 2025 14:31:25 +0300 Subject: [PATCH 06/12] refactor: remove useless file get content call --- src/Commands/InitCommand.php | 11 +---- tests/InitCommandTest.php | 36 +-------------- ...nv.development_clerk_credentials_added.yml | 2 + ...ent_clerk_credentials_added_mobile_app.yml | 2 + .../env.development_clerk_guard_added.yml | 41 ----------------- .../env.example_clerk_credentials_added.yml | 2 + ...ple_clerk_credentials_added_mobile_app.yml | 2 + .../env.example_clerk_guard_added.yml | 44 ------------------- 8 files changed, 12 insertions(+), 128 deletions(-) delete mode 100644 tests/fixtures/InitCommandTest/env.development_clerk_guard_added.yml delete mode 100644 tests/fixtures/InitCommandTest/env.example_clerk_guard_added.yml diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index 9b0e857..bbaf367 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -116,15 +116,8 @@ public function handle(): void if ($this->authType === AuthTypeEnum::Clerk) { $this->enableClerk(); - $this->createOrUpdateConfigFile('.env.development', '=', [ - 'AUTH_GUARD' => 'clerk', - ]); - - $this->createOrUpdateConfigFile($envFile, '=', [ - 'AUTH_GUARD' => 'clerk', - ]); - $data = [ + 'AUTH_GUARD' => 'clerk', 'CLERK_ALLOWED_ISSUER' => '', 'CLERK_SECRET_KEY' => '', 'CLERK_SIGNER_KEY_PATH' => '', @@ -134,8 +127,8 @@ public function handle(): void $data['CLERK_ALLOWED_ORIGINS'] = ''; } - $this->createOrUpdateConfigFile($envFile, '=', $data); $this->createOrUpdateConfigFile('.env.development', '=', $data); + $this->createOrUpdateConfigFile($envFile, '=', $data); if ($envFile !== '.env.example') { $this->createOrUpdateConfigFile('.env.example', '=', $data); diff --git a/tests/InitCommandTest.php b/tests/InitCommandTest.php index eb0b5f7..65b6a96 100644 --- a/tests/InitCommandTest.php +++ b/tests/InitCommandTest.php @@ -182,14 +182,6 @@ public function testRunWithAdminAndDefaultReadmeCreation() 'arguments' => ['.env.example'], 'result' => $this->getFixture('env.example.yml'), ], - [ - 'arguments' => ['.env.example'], - 'result' => $this->getFixture('env.example.yml'), - ], - [ - 'arguments' => ['.env.development'], - 'result' => $this->getFixture('env.development.yml'), - ], [ 'arguments' => [base_path('/vendor/ronasit/laravel-project-initializator/resources/md/readme/README.md')], 'result' => $this->getTemplate('README.md'), @@ -245,20 +237,12 @@ public function testRunWithAdminAndDefaultReadmeCreation() ], [ '.env.development', - $this->getFixture('env.development_clerk_guard_added.yml'), - ], - [ - '.env.example', - $this->getFixture('env.example_clerk_guard_added.yml'), + $this->getFixture('env.development_clerk_credentials_added.yml'), ], [ '.env.example', $this->getFixture('env.example_clerk_credentials_added.yml'), ], - [ - '.env.development', - $this->getFixture('env.development_clerk_credentials_added.yml'), - ], [ 'database/migrations/2018_11_11_111111_admins_create_table.php', $this->getFixture('admins_table_migration.php'), @@ -773,14 +757,6 @@ public function testRunWithClerkMobileApp(): void 'arguments' => ['.env.example'], 'result' => $this->getFixture('env.example.yml'), ], - [ - 'arguments' => ['.env.example'], - 'result' => $this->getFixture('env.example.yml'), - ], - [ - 'arguments' => ['.env.development'], - 'result' => $this->getFixture('env.development.yml'), - ], [ 'arguments' => [base_path('/vendor/ronasit/laravel-project-initializator/resources/md/readme/README.md')], 'result' => $this->getTemplate('README.md'), @@ -836,20 +812,12 @@ public function testRunWithClerkMobileApp(): void ], [ '.env.development', - $this->getFixture('env.development_clerk_guard_added.yml'), - ], - [ - '.env.example', - $this->getFixture('env.example_clerk_guard_added.yml'), + $this->getFixture('env.development_clerk_credentials_added_mobile_app.yml'), ], [ '.env.example', $this->getFixture('env.example_clerk_credentials_added_mobile_app.yml'), ], - [ - '.env.development', - $this->getFixture('env.development_clerk_credentials_added_mobile_app.yml'), - ], [ 'database/migrations/2018_11_11_111111_admins_create_table.php', $this->getFixture('admins_table_migration.php'), diff --git a/tests/fixtures/InitCommandTest/env.development_clerk_credentials_added.yml b/tests/fixtures/InitCommandTest/env.development_clerk_credentials_added.yml index 12062dc..4514a8b 100644 --- a/tests/fixtures/InitCommandTest/env.development_clerk_credentials_added.yml +++ b/tests/fixtures/InitCommandTest/env.development_clerk_credentials_added.yml @@ -38,6 +38,8 @@ FRONTEND_URL= JWT_SHOW_BLACKLIST_EXCEPTION=true +AUTH_GUARD=clerk + CLERK_ALLOWED_ISSUER= CLERK_SECRET_KEY= CLERK_SIGNER_KEY_PATH= diff --git a/tests/fixtures/InitCommandTest/env.development_clerk_credentials_added_mobile_app.yml b/tests/fixtures/InitCommandTest/env.development_clerk_credentials_added_mobile_app.yml index 3baa711..3d23e10 100644 --- a/tests/fixtures/InitCommandTest/env.development_clerk_credentials_added_mobile_app.yml +++ b/tests/fixtures/InitCommandTest/env.development_clerk_credentials_added_mobile_app.yml @@ -38,6 +38,8 @@ FRONTEND_URL= JWT_SHOW_BLACKLIST_EXCEPTION=true +AUTH_GUARD=clerk + CLERK_ALLOWED_ISSUER= CLERK_SECRET_KEY= CLERK_SIGNER_KEY_PATH= \ No newline at end of file diff --git a/tests/fixtures/InitCommandTest/env.development_clerk_guard_added.yml b/tests/fixtures/InitCommandTest/env.development_clerk_guard_added.yml deleted file mode 100644 index 22ba4d0..0000000 --- a/tests/fixtures/InitCommandTest/env.development_clerk_guard_added.yml +++ /dev/null @@ -1,41 +0,0 @@ -APP_NAME="My App" -APP_ENV=development -APP_KEY= -APP_DEBUG=true -APP_LOG_LEVEL=debug -APP_URL=https://mysite.com - -DB_CONNECTION=pgsql -DB_HOST= -DB_PORT= -DB_DATABASE= -DB_USERNAME= -DB_PASSWORD= - -BROADCAST_DRIVER=log -CACHE_DRIVER=file -SESSION_DRIVER=redis -QUEUE_CONNECTION=redis - -REDIS_HOST=redis -REDIS_PASSWORD= -REDIS_PORT= - -MAIL_DRIVER=smtp -MAIL_HOST= -MAIL_PORT= -MAIL_USERNAME= -MAIL_PASSWORD= -MAIL_ENCRYPTION= - -FILESYSTEM_DISK=gcs - -PUSHER_APP_ID= -PUSHER_APP_KEY= -PUSHER_APP_SECRET= - -FRONTEND_URL= - -JWT_SHOW_BLACKLIST_EXCEPTION=true - -AUTH_GUARD=clerk \ No newline at end of file diff --git a/tests/fixtures/InitCommandTest/env.example_clerk_credentials_added.yml b/tests/fixtures/InitCommandTest/env.example_clerk_credentials_added.yml index 7c1a023..a028066 100644 --- a/tests/fixtures/InitCommandTest/env.example_clerk_credentials_added.yml +++ b/tests/fixtures/InitCommandTest/env.example_clerk_credentials_added.yml @@ -41,6 +41,8 @@ FRONTEND_URL=http://localhost JWT_SECRET= JWT_SHOW_BLACKLIST_EXCEPTION=true +AUTH_GUARD=clerk + CLERK_ALLOWED_ISSUER= CLERK_SECRET_KEY= CLERK_SIGNER_KEY_PATH= diff --git a/tests/fixtures/InitCommandTest/env.example_clerk_credentials_added_mobile_app.yml b/tests/fixtures/InitCommandTest/env.example_clerk_credentials_added_mobile_app.yml index 923f0bf..e18317d 100644 --- a/tests/fixtures/InitCommandTest/env.example_clerk_credentials_added_mobile_app.yml +++ b/tests/fixtures/InitCommandTest/env.example_clerk_credentials_added_mobile_app.yml @@ -41,6 +41,8 @@ FRONTEND_URL=http://localhost JWT_SECRET= JWT_SHOW_BLACKLIST_EXCEPTION=true +AUTH_GUARD=clerk + CLERK_ALLOWED_ISSUER= CLERK_SECRET_KEY= CLERK_SIGNER_KEY_PATH= \ No newline at end of file diff --git a/tests/fixtures/InitCommandTest/env.example_clerk_guard_added.yml b/tests/fixtures/InitCommandTest/env.example_clerk_guard_added.yml deleted file mode 100644 index 067ccaf..0000000 --- a/tests/fixtures/InitCommandTest/env.example_clerk_guard_added.yml +++ /dev/null @@ -1,44 +0,0 @@ -APP_NAME="My App" -APP_ENV=local -APP_KEY= -APP_DEBUG=true -APP_LOG_LEVEL=debug -APP_URL=http://localhost - -DB_CONNECTION=pgsql -DB_HOST=pgsql -DB_PORT=5432 -DB_DATABASE=postgres -DB_USERNAME=postgres -DB_PASSWORD="" - -BROADCAST_DRIVER=log -CACHE_DRIVER=redis -SESSION_DRIVER=redis -QUEUE_CONNECTION=sync - -REDIS_HOST=redis -REDIS_PASSWORD=null -REDIS_PORT=6379 - -MAIL_DRIVER=smtp -MAIL_HOST=smtp.mailtrap.io -MAIL_PORT=2525 -MAIL_USERNAME=null -MAIL_PASSWORD=null -MAIL_ENCRYPTION=null - -FILESYSTEM_DISK=local -GOOGLE_CLOUD_STORAGE_BUCKET=ronasit-development -GOOGLE_CLOUD_PROJECT_ID=ronas-it-development - -PUSHER_APP_ID= -PUSHER_APP_KEY= -PUSHER_APP_SECRET= - -FRONTEND_URL=http://localhost - -JWT_SECRET= -JWT_SHOW_BLACKLIST_EXCEPTION=true - -AUTH_GUARD=clerk \ No newline at end of file From 34eee72093fc01c02561b6d2e28b10d829104e04 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Mon, 25 Aug 2025 15:36:57 +0300 Subject: [PATCH 07/12] fix:tests --- tests/InitCommandTest.php | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/tests/InitCommandTest.php b/tests/InitCommandTest.php index 7a1f3de..5523ba0 100644 --- a/tests/InitCommandTest.php +++ b/tests/InitCommandTest.php @@ -737,10 +737,6 @@ public function testRunWithClerkMobileApp(): void 'arguments' => ['.env.development'], 'result' => $this->getFixture('env.development.yml'), ], - [ - 'arguments' => ['config/auth.php'], - 'result' => $this->getFixture('auth.php'), - ], [ 'arguments' => ['.env.development'], 'result' => $this->getFixture('env.development.yml'), @@ -794,10 +790,6 @@ public function testRunWithClerkMobileApp(): void $this->mockFilePutContent( 'env.example.yml', 'env.development.yml', - [ - 'config/auth.php', - $this->getFixture('auth-modified.php'), - ], [ 'database/migrations/2018_11_11_111111_users_add_clerk_id_field.php', $this->getFixture('users_add_clerk_id_field_migration.php'), @@ -835,7 +827,7 @@ public function testRunWithClerkMobileApp(): void ['arguments' => 'php artisan vendor:publish --provider="RonasIT\AutoDoc\AutoDocServiceProvider" --ansi'], ['arguments' => 'composer require --dev ronasit/laravel-entity-generator --ansi'], ['arguments' => 'composer require ronasit/laravel-clerk --ansi'], - ['arguments' => 'php artisan vendor:publish --provider="RonasIT\\Clerk\\Providers\\ClerkServiceProvider" --ansi'], + ['arguments' => 'php artisan laravel-clerk:install --ansi'], ['arguments' => 'composer require ronasit/laravel-telescope-extension --ansi'], ['arguments' => 'php artisan telescope:install --ansi'], ); From eccc0b19020153bb13fcfe6ced0f54b17c395933 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Thu, 28 Aug 2025 12:56:05 +0300 Subject: [PATCH 08/12] fix: check --- src/Commands/InitCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index 8fb25cd..67eb0de 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -428,7 +428,7 @@ protected function createOrUpdateConfigFile(string $fileName, string $separator, $item = "{$key}{$separator}{$value}"; - if (Str::before($key, '_') === Str::before($previousKey, '_')) { + if (!empty($previousKey) && Str::before($key, '_') === Str::before($previousKey, '_')) { $lines[] = $item; } else { $lines[] = "\n{$item}"; From a9f09209771e7bde6ec14aee12d98bac0d87fec1 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Thu, 28 Aug 2025 14:09:58 +0300 Subject: [PATCH 09/12] refactor: add method check prefix --- src/Commands/InitCommand.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index 67eb0de..9f2e7aa 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -428,7 +428,7 @@ protected function createOrUpdateConfigFile(string $fileName, string $separator, $item = "{$key}{$separator}{$value}"; - if (!empty($previousKey) && Str::before($key, '_') === Str::before($previousKey, '_')) { + if (!empty($previousKey) && $this->configFileHaveSameLinePrefix($key, $previousKey)) { $lines[] = $item; } else { $lines[] = "\n{$item}"; @@ -442,6 +442,11 @@ protected function createOrUpdateConfigFile(string $fileName, string $separator, file_put_contents($fileName, $ymlSettings); } + protected function configFileHaveSameLinePrefix(string $key, string $previousKey): bool + { + return Str::before($key, '_') === Str::before($previousKey, '_'); + } + protected function loadReadmePart(string $fileName): string { $file = base_path(DIRECTORY_SEPARATOR . self::TEMPLATES_PATH . DIRECTORY_SEPARATOR . $fileName); From 44a01f47433aeed5fc6d979af924c057ee8f47a9 Mon Sep 17 00:00:00 2001 From: DenTray Date: Mon, 1 Sep 2025 21:44:32 +0600 Subject: [PATCH 10/12] Apply suggestions from code review --- src/Commands/InitCommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index 9f2e7aa..c123eed 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -428,7 +428,7 @@ protected function createOrUpdateConfigFile(string $fileName, string $separator, $item = "{$key}{$separator}{$value}"; - if (!empty($previousKey) && $this->configFileHaveSameLinePrefix($key, $previousKey)) { + if (!empty($previousKey) && $this->configKeysHaveSamePrefix($key, $previousKey)) { $lines[] = $item; } else { $lines[] = "\n{$item}"; @@ -442,7 +442,7 @@ protected function createOrUpdateConfigFile(string $fileName, string $separator, file_put_contents($fileName, $ymlSettings); } - protected function configFileHaveSameLinePrefix(string $key, string $previousKey): bool + protected function configKeysHaveSamePrefix(string $key, string $previousKey): bool { return Str::before($key, '_') === Str::before($previousKey, '_'); } From 888c736a0f144bbb3f05acc48cb8cb8f37050670 Mon Sep 17 00:00:00 2001 From: DenTray Date: Mon, 1 Sep 2025 21:45:00 +0600 Subject: [PATCH 11/12] Update src/Commands/InitCommand.php --- src/Commands/InitCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index c123eed..9b60221 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -103,7 +103,7 @@ public function handle(): void $this->choice( question: 'What type of application will your API serve?', choices: AppTypeEnum::values(), - default: AppTypeEnum::Multiplatform->value + default: AppTypeEnum::Multiplatform->value, ) ); From 471b047f11c4e1b1a1d98d48002a9407b628c473 Mon Sep 17 00:00:00 2001 From: DenTray Date: Mon, 1 Sep 2025 21:45:33 +0600 Subject: [PATCH 12/12] Update src/Commands/InitCommand.php --- src/Commands/InitCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index 9b60221..c894a1d 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -104,7 +104,7 @@ public function handle(): void question: 'What type of application will your API serve?', choices: AppTypeEnum::values(), default: AppTypeEnum::Multiplatform->value, - ) + ), ); $this->authType = AuthTypeEnum::from($this->choice(