├── .github ├── FUNDING.yaml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── tests.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── bin ├── release.sh └── test.sh ├── composer.json ├── docs ├── README.md └── commands │ ├── make-action.md │ ├── make-adr-action.md │ ├── make-builder.md │ ├── make-cast.md │ ├── make-collection.md │ ├── make-command.md │ ├── make-controller.md │ ├── make-data.md │ ├── make-enum.md │ ├── make-event.md │ ├── make-job.md │ ├── make-listener.md │ ├── make-model.md │ ├── make-observer.md │ ├── make-policy.md │ ├── make-process.md │ ├── make-provider.md │ ├── make-query.md │ ├── make-request.md │ ├── make-resource.md │ ├── make-rule.md │ ├── make-scope.md │ └── publish-gate.md ├── phpstan.neon ├── phpunit.xml ├── pint.json ├── src ├── Actions │ ├── CopyAndRefactorDirectoryAction.php │ ├── CopyAndRefactorFileAction.php │ ├── CopyDirectoryAction.php │ ├── CopyFileAction.php │ ├── CreateDirectoryAction.php │ ├── CreateFileAction.php │ ├── DeletePathAction.php │ ├── MoveAndRefactorFileAction.php │ ├── MoveFileAction.php │ ├── NormalizePathAction.php │ └── RefactorFileAction.php ├── Affiliation.php ├── Commands │ ├── Abstracts │ │ ├── ApplicationCommand.php │ │ ├── BaseCommand.php │ │ ├── DomainCommand.php │ │ └── SupportCommand.php │ ├── MakeActionCommand.php │ ├── MakeAdrActionCommand.php │ ├── MakeBuilderCommand.php │ ├── MakeCastCommand.php │ ├── MakeCollectionCommand.php │ ├── MakeCommandCommand.php │ ├── MakeControllerCommand.php │ ├── MakeDataTransferObjectCommand.php │ ├── MakeEnumCommand.php │ ├── MakeEventCommand.php │ ├── MakeJobCommand.php │ ├── MakeListenerCommand.php │ ├── MakeModelCommand.php │ ├── MakeObserverCommand.php │ ├── MakePolicyCommand.php │ ├── MakeProcessCommand.php │ ├── MakeQueryCommand.php │ ├── MakeRequestCommand.php │ ├── MakeResourceCommand.php │ ├── MakeRuleCommand.php │ ├── MakeScopeCommand.php │ ├── MakeServiceProviderCommand.php │ └── PublishBeyondGateCommand.php ├── Exceptions │ ├── AlreadyExistsException.php │ ├── InvalidNameException.php │ └── RequiredPackagesAreMissingException.php ├── LaravelBeyondServiceProvider.php ├── NameResolver.php ├── Type.php └── helper.php ├── stubs ├── action.stub ├── beyond.gate.stub ├── builder.stub ├── cast.stub ├── collection.plain.stub ├── collection.stub ├── command.stub ├── controller.api.stub ├── controller.invokable.stub ├── controller.stub ├── data-transfer-object.stub ├── enum.stub ├── event.stub ├── job.stub ├── job.sync.stub ├── listener.stub ├── middleware.stub ├── model.stub ├── observer.stub ├── policy.stub ├── process.stub ├── query.stub ├── request.stub ├── resource.collection.stub ├── resource.stub ├── rule.stub ├── scope.stub └── service.provider.stub └── tests ├── BaseTest.php ├── Commands ├── MakeActionCommandTest.php ├── MakeAdrActionCommandTest.php ├── MakeBuilderCommandTest.php ├── MakeCastCommandTest.php ├── MakeCollectionCommandTest.php ├── MakeCommandCommandTest.php ├── MakeControllerCommandTest.php ├── MakeDataTransferObjectCommandTest.php ├── MakeEnumCommandTest.php ├── MakeEventCommandTest.php ├── MakeJobCommandTest.php ├── MakeListenerCommandTest.php ├── MakeModelCommandTest.php ├── MakeObserverCommandTest.php ├── MakePolicyCommandTest.php ├── MakeProcessCommandTest.php ├── MakeQueryCommandTest.php ├── MakeRequestCommandTest.php ├── MakeResourceCommandTest.php ├── MakeRuleCommandTest.php ├── MakeScopeCommandTest.php ├── MakeServiceProviderCommandTest.php └── PublishBeyondGateCommandTest.php └── TestCase.php /.github/FUNDING.yaml: -------------------------------------------------------------------------------- 1 | github: [akrillia] 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG]: " 5 | labels: bug 6 | assignees: alexanderkroneis, regnerisch 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Environment (please complete the following information):** 27 | - PHP: [e.g. 8.2] 28 | - Laravel Version: [e.g. 11.7] 29 | - Beyond Version: [e.g. 7.0] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FEATURE]: " 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | ci: 7 | runs-on: ${{ matrix.os }} 8 | strategy: 9 | matrix: 10 | os: [ubuntu-latest, windows-latest, macos-14] 11 | php: ['8.2', '8.3', '8.4'] 12 | laravel: [12.*, 11.*] 13 | include: 14 | - laravel: 12.* 15 | - testbench: 10.* 16 | - laravel: 11.* 17 | testbench: 9.* 18 | 19 | steps: 20 | - name: Checkout 21 | uses: actions/checkout@v2 22 | 23 | - name: Setup PHP 24 | uses: shivammathur/setup-php@v2 25 | with: 26 | php-version: ${{ matrix.php }} 27 | extensions: fileinfo 28 | tools: composer:v2 29 | coverage: none 30 | 31 | - name: Install dependencies 32 | run: | 33 | composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update 34 | composer update --prefer-dist --no-interaction 35 | 36 | - name: Unit Tests 37 | run: vendor/bin/phpunit --colors=always 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .phpunit.cache/ 3 | vendor/ 4 | 5 | .DS_Store 6 | .php-cs-fixer.cache 7 | .phpunit.result.cache 8 | composer.lock 9 | tools/release-it.sh 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [Unreleased] 8 | 9 | ## [7.1.0] - 2025-03-10 10 | ### Added 11 | - Add `beyond:make:adr-action` command by [@regnerisch](https://github.com/regnerisch) 12 | - Support for Laravel 12.x by [@regnerisch](https://github.com/regnerisch) 13 | 14 | ### Removed 15 | - Support for Laravel 10.x by [@regnerisch](https://github.com/regnerisch) 16 | 17 | ## [7.0.4] - 2024-07-31 18 | ### Changed 19 | - Changelog by [@regnerisch](https://github.com/regnerisch) 20 | 21 | ## [7.0.3] - 2024-07-31 22 | ### Fixed 23 | - Version mismatch by [@regnerisch](https://github.com/regnerisch) 24 | 25 | ## [7.0.2] - Deleted due version mismatch 26 | ### Changed 27 | - Stubs by [@regnerisch](https://github.com/regnerisch) 28 | 29 | ## [7.0.1] - Deleted due version mismatch 30 | ### Changed 31 | - Changelog by [@regnerisch](https://github.com/regnerisch) 32 | 33 | ## [7.0.0] - 2024-07-26 34 | ### Added 35 | - Documentation by [@regnerisch](https://github.com/regnerisch) 36 | 37 | ## [7.0.0-beta.8] - 2024-04-24 38 | ### Added 39 | - Universal usable `--global` flag by [@regnerisch](https://github.com/regnerisch) 40 | 41 | ### Fixed 42 | - Access before initialization by [@regnerisch](https://github.com/regnerisch) in [#100](https://github.com/akrillia/laravel-beyond/issues/100) reported by [@napruzzese](https://github.com/napruzzese) 43 | 44 | ### Changed 45 | - Refactor directory structure, tests and much more by [@regnerisch](https://github.com/regnerisch) 46 | 47 | ### Removed 48 | - Removed Commands: `beyond:make:app`, `beyond:make:middleware`, `beyond:make:migration`, `beyond:make:notification`, `beyond:publish:deptrac` by [@regnerisch](https://github.com/regnerisch) 49 | 50 | ## [7.0.0-beta.7] - 2023-12-18 51 | ### Changed 52 | - Change directory structure back to v6, as it seems to be a better one by [@regnerisch](https://github.com/regnerisch) 53 | 54 | ## [7.0.0-beta.6] - 2023-12-01 55 | ### Added 56 | - Add missing changes in CHANGELOG.md by [@regnerisch](https://github.com/regnerisch) 57 | 58 | ### Changed 59 | - Change module selection by [@regnerisch](https://github.com/regnerisch) 60 | 61 | ## [7.0.0-beta.5] - 2023-12-01 62 | ### Added 63 | - Add tests by [@alexanderkroneis](https://github.com/alexanderkroneis) 64 | - Add windows tests by [@alexanderkroneis](https://github.com/alexanderkroneis) in [#98](https://github.com/akrillia/laravel-beyond/pull/98) 65 | - Add deptrac config and publish command by [@regnerisch](https://github.com/regnerisch) [#38](https://github.com/akrillia/laravel-beyond/issues/38) 66 | - Add `MakeTestCommand` by [@regnerisch](https://github.com/regnerisch) [#92](https://github.com/akrillia/laravel-beyond/issues/92) 67 | - Add documentation to repository by [@regnerisch](https://github.com/regnerisch) [#34](https://github.com/akrillia/laravel-beyond/issues/34) 68 | 69 | ### Fixed 70 | - Fix wrong use statement by [@regnerisch](https://github.com/regnerisch) [#94](https://github.com/akrillia/laravel-beyond/issues/94) 71 | 72 | ### Changed 73 | - Rename `DataTransferObjects` to `DataObjects` by [@alexanderkroneis](https://github.com/alexanderkroneis) in [#97](https://github.com/akrillia/laravel-beyond/pull/97) 74 | 75 | ### Removed 76 | - Support for php8.1 by [@regnerisch](https://github.com/regnerisch) 77 | 78 | ## [7.0.0-beta.4] - 2023-08-07 79 | ### Added 80 | - Add `beyond:make:migration` command by [@regnerisch](https://github.com/regnerisch) 81 | - Add [phpstan](https://github.com/phpstan/phpstan) and fix errors by [@regnerisch](https://github.com/regnerisch) 82 | - Add support for additional directories `beyond:make:controller User.Admin/UserController` by [@regnerisch](https://github.com/regnerisch) 83 | 84 | ### Fixed 85 | - Fix module choice attempts by [@regnerisch](https://github.com/regnerisch) 86 | 87 | ### Changed 88 | - Replace `pest` with `phpunit` by [@regnerisch](https://github.com/regnerisch) 89 | - Changed `beyond:make:{command} Module/ClassName` to `beyond:make:{command} Module.ClassName` to support directories by [@regnerisch](https://github.com/regnerisch) 90 | 91 | ## [7.0.0-beta.3] - 2023-08-04 92 | ### Changed 93 | - Update dependencies by [@regnerisch](https://github.com/regnerisch) 94 | 95 | ## [7.0.0-beta.2] - 2023-08-03 96 | ### Added 97 | - Add alias for `beyond:make:dto` by [@regnerisch](https://github.com/regnerisch) 98 | 99 | ### Fixed 100 | - Fixed some messages by [@regnerisch](https://github.com/regnerisch) 101 | 102 | ### Changed 103 | - Swap deprecated rule interface by [@regnerisch](https://github.com/regnerisch) 104 | - Swap default behaviour on `beyond:make:module` by [@regnerisch](https://github.com/regnerisch) 105 | 106 | ## [7.0.0-beta.1] - 2023-03-19 107 | 108 | ## [6.0.1] - 2023-02-22 109 | 110 | ## [6.0.0] - 2023-02-22 111 | ### Added 112 | - Laravel 10.x support by [@regnerisch](https://github.com/regnerisch) 113 | 114 | ### Removed 115 | - Laravel-Command-Hooks Dependency by [@regnerisch](https://github.com/regnerisch) 116 | 117 | ## [5.4.1] - 2023-01-10 118 | ### Added 119 | - Preparation for Laravel 10 by [@alexgaal](https://github.com/alexgaal) 120 | 121 | ## [5.3.2] - 2023-01-10 122 | ### Fixed 123 | - Wrong namespace in UPGRADE.md by [@alexgaal](https://github.com/alexgaal) 124 | - Used wrong function of `Schema` when creating a migration by [@alexgaal](https://github.com/alexgaal) 125 | 126 | ## [5.3.1] - 2022-12-11 127 | ### Added 128 | - Add test for PHP 8.2 to ensure compatibility by [@alexgaal](https://github.com/alexgaal) 129 | 130 | ## [5.2.1] - 2022-11-30 131 | ### Fixed 132 | - Old if conditions in MakeControllerCommand by [@bleakprestiger](https://github.com/bleakprestiger) 133 | 134 | ## [5.2.0] - 2022-11-28 135 | ### Added 136 | - Observer Command by [@krishnahimself](https://github.com/krishnahimself) 137 | - Notification Command by [@alexgaal](https://github.com/alexgaal) 138 | 139 | ## [5.1.0] - 2022-11-25 140 | ### Added 141 | - Trait Command by [@dimzeta](https://github.com/dimzeta) 142 | 143 | ### Fixed 144 | - Factory stub in README.md by [@krishnahimself](https://github.com/krishnahimself) 145 | - Improved install instructions in README.md by [@Wulfheart](https://github.com/Wulfheart) 146 | 147 | ## [5.0.0] - 2022-11-16 148 | ### Fixed 149 | - Fix missing links in CHANGELOG.md by [@regnerisch](https://github.com/regnerisch) 150 | 151 | ### Changed 152 | - Changed namespace from `Regnerisch` to `AkrilliA` by [@regnerisch](https://github.com/regnerisch) 153 | - Changed package name from `regnerisch/laravel-beyond` to `akrillia/laravel-beyond` by [@regnerisch](https://github.com/regnerisch) 154 | 155 | ## [4.0.1] - 2022-09-26 156 | ### Fixed 157 | - Fix `migration` and `factory` shortcut flags by [@krishnahimself](https://github.com/krishnahimself) in [#73](https://github.com/akrillia/laravel-beyond/pull/73) 158 | 159 | ## [4.0.0] - 2022-09-23 160 | ### Added 161 | - `MakeDataTransferObjectFactoryCommand` by [@regnerisch](https://github.com/regnerisch) reported by [@thewebartisan7](https://github.com/thewebartisan7) in [#58](https://github.com/akrillia/laravel-beyond/pull/58) 162 | - Extend the default `Controller` of Laravel by [@regnerisch](https://github.com/regnerisch) reported by [@thewebartisan7](https://github.com/thewebartisan7) in [#63](https://github.com/akrillia/laravel-beyond/issues/63) 163 | - UPGRADE.md by [@alexgaal](https://github.com/alexgaal) 164 | 165 | ### Changed 166 | - Reset folder structure by [@regnerisch](https://github.com/regnerisch) reported by [@thewebartisan7](https://github.com/thewebartisan7) in [#56](https://github.com/akrillia/laravel-beyond/issues/56) 167 | - Use `regnerisch/laravel-command-hooks` instead of custom `BaseCommand` by [@regnerisch](https://github.com/regnerisch) 168 | - Rename `--overwrite` to `--force` to be more Laravel compatible by [@regnerisch](https://github.com/regnerisch) 169 | 170 | ### Fixed 171 | - Fix commands not autoloaded by [@regnerisch](https://github.com/regnerisch) reported by [@dimzeta](https://github.com/dimzeta) in [#66](https://github.com/akrillia/laravel-beyond/issues/66) 172 | 173 | ## [3.2.1] - 2022-09-22 174 | ### Added 175 | - Missing contributor by [@regnerisch](https://github.com/regnerisch) 176 | 177 | ## [3.2.0] - 2022-09-22 178 | ### Added 179 | - `invokable` flag on `MakeControllerCommand` by [@dimzeta](https://github.com/dimzeta) in [#67](https://github.com/akrillia/laravel-beyond/pull/67) 180 | 181 | ### Fixed 182 | - Fix some CHANGELOG typos and links by [@regnerisch](https://github.com/regnerisch) 183 | 184 | ## [3.1.1] - 2022-09-15 185 | ### Changed 186 | - Use FQN instead of classname in `SetupCommand` output by [@Wulfheart](https://github.com/Wulfheart) in [#70](https://github.com/akrillia/laravel-beyond/pull/70) 187 | 188 | ## [3.1.0] - 2022-09-01 189 | ### Added 190 | - Queueable Actions by [@thewebartisan7](https://github.com/thewebartisan7) in [#64](https://github.com/akrillia/laravel-beyond/pull/64) 191 | 192 | ### Changed 193 | - Change changelog schema from "Conventional changelog" to "Keep a changelog" by [@regnerisch](https://github.com/regnerisch) 194 | 195 | ### Fixed 196 | - Drop table in `down` method by [@thewebartisan7](https://github.com/thewebartisan7) in [#55](https://github.com/akrillia/laravel-beyond/pull/55) 197 | 198 | ### Removed 199 | - Remove auto generation of changelog in release it by [@regnerisch](https://github.com/regnerisch) 200 | 201 | [Unreleased]: https://github.com/regnerisch/laravel-beyond/compare/v7.1.0...HEAD 202 | [7.1.0]: https://github.com/regnerisch/laravel-beyond/compare/v7.0.4...v7.1.0 203 | [7.0.4]: https://github.com/regnerisch/laravel-beyond/compare/v7.0.3...v7.0.4 204 | [7.0.3]: https://github.com/regnerisch/laravel-beyond/compare/v7.0.0...v7.0.3 205 | [7.0.0]: https://github.com/regnerisch/laravel-beyond/compare/v7.0.0-beta.8...v7.0.0 206 | [7.0.0-beta.8]: https://github.com/regnerisch/laravel-beyond/compare/v7.0.0-beta.7...v7.0.0-beta.8 207 | [7.0.0-beta.7]: https://github.com/regnerisch/laravel-beyond/compare/v7.0.0-beta.6...v7.0.0-beta.7 208 | [7.0.0-beta.6]: https://github.com/regnerisch/laravel-beyond/compare/v7.0.0-beta.5...v7.0.0-beta.6 209 | [7.0.0-beta.5]: https://github.com/regnerisch/laravel-beyond/compare/v7.0.0-beta.4...v7.0.0-beta.5 210 | [7.0.0-beta.4]: https://github.com/regnerisch/laravel-beyond/compare/v7.0.0-beta.3...v7.0.0-beta.4 211 | [7.0.0-beta.3]: https://github.com/regnerisch/laravel-beyond/compare/v7.0.0-beta.2...v7.0.0-beta.3 212 | [7.0.0-beta.2]: https://github.com/regnerisch/laravel-beyond/compare/v7.0.0-beta.1...v7.0.0-beta.2 213 | [7.0.0-beta.1]: https://github.com/regnerisch/laravel-beyond/compare/v6.0.1...v7.0.0-beta.1 214 | [6.0.1]: https://github.com/regnerisch/laravel-beyond/compare/v6.0.0...v6.0.1 215 | [6.0.0]: https://github.com/regnerisch/laravel-beyond/compare/v5.4.1...v6.0.0 216 | [5.4.1]: https://github.com/regnerisch/laravel-beyond/compare/v5.3.2...v5.4.1 217 | [5.3.2]: https://github.com/regnerisch/laravel-beyond/compare/v5.3.1...v5.3.2 218 | [5.3.1]: https://github.com/regnerisch/laravel-beyond/compare/v5.3.0...v5.3.1 219 | [5.3.0]: https://github.com/regnerisch/laravel-beyond/compare/v5.2.1...v5.3.0 220 | [5.2.1]: https://github.com/regnerisch/laravel-beyond/compare/v5.2.0...v5.2.1 221 | [5.2.0]: https://github.com/regnerisch/laravel-beyond/compare/v5.1.0...v5.2.0 222 | [5.1.0]: https://github.com/regnerisch/laravel-beyond/compare/v5.0.0...v5.1.0 223 | [5.0.0]: https://github.com/regnerisch/laravel-beyond/compare/v4.0.1...v5.0.0 224 | [4.0.1]: https://github.com/regnerisch/laravel-beyond/compare/v4.0.0...v4.0.1 225 | [4.0.0]: https://github.com/regnerisch/laravel-beyond/compare/v3.2.1...v4.0.0 226 | [3.2.1]: https://github.com/regnerisch/laravel-beyond/compare/v3.2.0...v3.2.1 227 | [3.2.0]: https://github.com/regnerisch/laravel-beyond/compare/v3.1.1...v3.2.0 228 | [3.1.1]: https://github.com/regnerisch/laravel-beyond/compare/v3.1.0...v3.1.1 229 | [3.1.0]: https://github.com/regnerisch/laravel-beyond/compare/v3.0.0...v3.1.0 230 | [3.0.0]: https://github.com/regnerisch/laravel-beyond/compare/v2.0.0...v3.0.0 231 | [2.0.0]: https://github.com/regnerisch/laravel-beyond/compare/v1.0.0...v2.0.0 232 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2022 Jonas Regner 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 4 | 5 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Beyond 2 | 3 | *This package is inspired by "[Laravel Beyond CRUD](https://spatie.be/products/laravel-beyond-crud)" from Spatie 4 | and "[Modularising the Monolith](https://www.youtube.com/watch?v=0Rq-yHAwYjQ&t=4129s)" from Ryuta Hamasaki.* 5 | 6 | This package will help you with `beyond:make` commands to easily create classes inside your "Laravel Beyond CRUD" 7 | inspired application. 8 | 9 | In version 7 we changed the way how Laravel Beyond works. We now do no longer change Laravels default 10 | directory structure, instead we place the DDD structure inside a separate `src` directory. This ensures 11 | compatibility with any other (Laravel related) package. 12 | 13 | ## Installation 14 | 15 | Install laravel-beyond with composer: 16 | ```bash 17 | composer require --dev akrillia/laravel-beyond 18 | ``` 19 | 20 | Add Laravel Beyonds namespaces inside your `composer.json`: 21 | ```json 22 | { 23 | // ... 24 | "autoload": { 25 | "psr-4": { 26 | "App\\": "app/", 27 | "Database\\Factories\\": "database/factories/", 28 | "Database\\Seeders\\": "database/seeders/", 29 | "Application\\": "src/Application", 30 | "Domain\\": "src/Domain", 31 | "Support\\": "src/Support" 32 | } 33 | }, 34 | // ... 35 | } 36 | ``` 37 | 38 | > [!WARNING] 39 | > Do not forget to run `composer dump-autoload` after adding the namespaces. 40 | 41 | ## Documentation 42 | Take a look at our documentation inside [`/docs`](docs/README.md) to learn about the available 43 | commands and how to use them. 44 | 45 | ## Directory structure 46 | ``` 47 | |- src 48 | | |- Application 49 | | | |- Admin 50 | | | | |- Commands 51 | | | | |- Controllers 52 | | | | |- Jobs 53 | | | | |- Policies 54 | | | | |- Processes 55 | | | | |- Queries 56 | | | | |- Requests 57 | | | | |- Resources 58 | | |- Domain 59 | | | |- User 60 | | | | |- Actions 61 | | | | |- Builder 62 | | | | |- Collections 63 | | | | |- DataObjects 64 | | | | |- Enums 65 | | | | |- Events 66 | | | | |- Listeners 67 | | | | |- Models 68 | | | | |- Observers 69 | | |- Support 70 | | | |- Casts 71 | | | |- Providers 72 | | | |- Rules 73 | ``` 74 | 75 | ## Contributors 76 | 77 | | Maintainer | Maintainer | 78 | |:--------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------:| 79 | | ![Maintainer regnerisch](https://avatars.githubusercontent.com/u/9422737?size=120&v=4) | ![Maintainer alexanderkroneis](https://avatars.githubusercontent.com/u/12985989?size=120&v=4) | 80 | | [@regnerisch](https://github.com/regnerisch) | [@alexanderkroneis](https://github.com/alexanderkroneis) | 81 | 82 | **Contributors:** 83 | - [@nilsvennemann](https://github.com/nilsvennemann) 84 | - [@Enaah](https://github.com/Enaah) 85 | - [@thewebartisan7](https://github.com/thewebartisan7) 86 | - [@Wulfheart](https://github.com/Wulfheart) 87 | - [@dimzeta](https://github.com/dimzeta) 88 | - [@krishnahimself](https://github.com/krishnahimself) 89 | 90 | ## License 91 | 92 | [ISC](LICENSE.md) 93 | -------------------------------------------------------------------------------- /bin/release.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | # Make sure the release tag is provided. 6 | if (( "$#" != 1 )) 7 | then 8 | echo "Tag has to be provided." 9 | 10 | exit 1 11 | fi 12 | 13 | RELEASE_BRANCH="7.x" 14 | CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) 15 | VERSION=$1 16 | 17 | # Make sure all tests are successful 18 | if ! bash bin/test.sh > /dev/null 2>&1; then 19 | echo "Tests did not complete without errors!" 20 | exit 1 21 | fi 22 | 23 | COMPOSER_JSON="composer.json" 24 | if ! grep -q "\"version\": \"$VERSION\"," "$COMPOSER_JSON"; then 25 | echo "Version mismatch with composer.json. Did you forget to update version?" 26 | exit 1 27 | fi 28 | 29 | # Make sure current branch and release branch match. 30 | if [[ "$RELEASE_BRANCH" != "$CURRENT_BRANCH" ]] 31 | then 32 | echo "Release branch ($RELEASE_BRANCH) does not match the current active branch ($CURRENT_BRANCH)." 33 | exit 1 34 | fi 35 | 36 | # Make sure the working directory is clear. 37 | if [[ -n "$(git status --porcelain)" ]] 38 | then 39 | echo "Your working directory is dirty. Did you forget to commit your changes?" 40 | exit 1 41 | fi 42 | 43 | # Make sure latest changes are fetched first. 44 | git fetch origin 45 | 46 | # Make sure that release branch is in sync with origin. 47 | if [[ $(git rev-parse HEAD) != $(git rev-parse origin/$RELEASE_BRANCH) ]] 48 | then 49 | echo "Your branch is out of date with its upstream. Did you forget to pull or push any changes before releasing?" 50 | exit 1 51 | fi 52 | 53 | # Always prepend with "v" 54 | if [[ $VERSION != v* ]] 55 | then 56 | VERSION="v$VERSION" 57 | fi 58 | 59 | # Tag Package 60 | git tag "$VERSION" 61 | git push origin --tags 62 | -------------------------------------------------------------------------------- /bin/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | PHP_VERSION="8.2" 4 | 5 | if ! docker info > /dev/null 2>&1; then 6 | echo "Please start docker first" 7 | exit 0 8 | fi 9 | 10 | echo "Running pint..." 11 | if ! docker run -it --rm -v "$PWD":/app -w /app php:"$PHP_VERSION"-cli php vendor/bin/pint; then 12 | exit 1 13 | fi 14 | 15 | echo "Running phpstan..." 16 | if ! docker run -it --rm -v "$PWD":/app -w /app php:"$PHP_VERSION"-cli php vendor/bin/phpstan analyse; then 17 | exit 1 18 | fi 19 | 20 | echo "Running phpunit..." 21 | if ! docker run -it --rm -v "$PWD":/app -w /app php:"$PHP_VERSION"-cli php vendor/bin/phpunit; then 22 | exit 1 23 | fi 24 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "akrillia/laravel-beyond", 3 | "type": "library", 4 | "license": "ISC", 5 | "version": "7.1.0", 6 | "autoload": { 7 | "psr-4": { 8 | "AkrilliA\\LaravelBeyond\\": "src/" 9 | }, 10 | "files": [ 11 | "src/helper.php" 12 | ] 13 | }, 14 | "autoload-dev": { 15 | "psr-4": { 16 | "Tests\\": "tests/" 17 | } 18 | }, 19 | "authors": [ 20 | { 21 | "name": "Jonas Regner", 22 | "email": "regnerjonas@protonmail.com" 23 | }, 24 | { 25 | "name": "Alexander Gaal", 26 | "email": "alexander.gaal@gipfel.dev" 27 | } 28 | ], 29 | "require": { 30 | "php": "^8.2", 31 | "ext-fileinfo": "^8.2", 32 | "illuminate/support": "^11.0|^12.0", 33 | "illuminate/console": "^11.0|^12.0", 34 | "illuminate/filesystem": "^11.0|^12.0", 35 | "laravel/prompts": "^v0.3.5" 36 | }, 37 | "extra": { 38 | "laravel": { 39 | "providers": [ 40 | "AkrilliA\\LaravelBeyond\\LaravelBeyondServiceProvider" 41 | ] 42 | } 43 | }, 44 | "require-dev": { 45 | "phpunit/phpunit": "^v11.0", 46 | "orchestra/testbench": "^9.1|^10.1", 47 | "laravel/pint": "^v1.21", 48 | "spatie/laravel-query-builder": "^6.3.1", 49 | "spatie/laravel-data": "^4.13", 50 | "spatie/laravel-queueable-action": "^2.16", 51 | "phpstan/phpstan": "^2.1" 52 | }, 53 | "minimum-stability": "dev" 54 | } 55 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Documentation 2 | 3 | > [!CAUTION] 4 | > Keep in mind: Laravel Beyond is a dev dependency. Do not use its helper functions like 5 | > `beyond_path`, `beyond_app_path`, `beyond_domain_path` or others. 6 | 7 | ## Commands 8 | ### Application 9 | - [`beyond:make:command`](commands/make-command.md) 10 | - [`beyond:make:controller`](commands/make-controller.md) 11 | - [`beyond:make:job`](commands/make-job.md) 12 | - [`beyond:make:policy`](commands/make-policy.md) 13 | - [`beyond:make:process`](commands/make-process.md) 14 | - [`beyond:make:query`](commands/make-query.md) 15 | - [`beyond:make:request`](commands/make-request.md) 16 | - [`beyond:make:resource`](commands/make-resource.md) 17 | 18 | ### Domain 19 | - [`beyond:make:action`](commands/make-action.md) 20 | - [`beyond:make:builder`](commands/make-builder.md) 21 | - [`beyond:make:collection`](commands/make-collection.md) 22 | - [`beyond:make:data`](commands/make-data.md) 23 | - [`beyond:make:enum`](commands/make-enum.md) 24 | - [`beyond:make:event`](commands/make-event.md) 25 | - [`beyond:make:listener`](commands/make-listener.md) 26 | - [`beyond:make:model`](commands/make-model.md) 27 | - [`beyond:make:observer`](commands/make-observer.md) 28 | - [`beyond:make:scope`](commands/make-scope.md) 29 | 30 | ### Support 31 | - [`beyond:make:cast`](commands/make-cast.md) 32 | - [`beyond:make:provider`](commands/make-provider.md) 33 | - [`beyond:make:rule`](commands/make-rule.md) 34 | 35 | ### Other 36 | - [`beyond:publish:gate`](commands/publish-gate.md) 37 | -------------------------------------------------------------------------------- /docs/commands/make-action.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:action` 2 | Creates a new action. An action does run one specific task, e.g. storing or updating a model. 3 | If you need to do additional tasks like sending e-mails you should wrap those inside their 4 | own action or (maybe better) consider using a [process](make-process.md). 5 | 6 | ## Signature 7 | `beyond:make:action {name} {--force}` 8 | 9 | | Parameters | Description | 10 | |------------|-------------------------| 11 | | name | The name of your action | 12 | 13 | | Flags | Description | 14 | |---------|-------------------------| 15 | | --force | Overwrite existing file | 16 | -------------------------------------------------------------------------------- /docs/commands/make-adr-action.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:adr:action` 2 | Creates a new ADR action. 3 | 4 | ## Signature 5 | `beyond:make:adr:action {name} {--force}` 6 | 7 | | Parameters | Description | 8 | |------------|-----------------------------| 9 | | name | The name of your adr action | 10 | 11 | | Flags | Description | 12 | |-------------|---------------------------------| 13 | | --force | Overwrite existing file | 14 | -------------------------------------------------------------------------------- /docs/commands/make-builder.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:builder` 2 | Creates a new Laravel Eloquent builder for a model. 3 | 4 | > [!NOTE] 5 | > You need to add the builder to your model 6 | > ```php 7 | > public function newEloquentBuilder($query): Builder 8 | > { 9 | > return new UserBuilder($query); 10 | > } 11 | > ``` 12 | 13 | > [!NOTE] 14 | > For proper IDE support add the following docblock to you model 15 | > ```php 16 | > /** 17 | > * @method static UserBuilder query() 18 | > */ 19 | > class User extends Model 20 | > ``` 21 | 22 | ## Signature 23 | `beyond:make:builder {name} {--force}` 24 | 25 | | Parameters | Description | 26 | |------------|--------------------------| 27 | | name | The name of your builder | 28 | 29 | | Flags | Description | 30 | |---------|-------------------------| 31 | | --force | Overwrite existing file | 32 | -------------------------------------------------------------------------------- /docs/commands/make-cast.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:cast` 2 | Creates a new cast. 3 | 4 | ## Signature 5 | `beyond:make:cast {name} {--force}` 6 | 7 | | Parameters | Description | 8 | |------------|-----------------------| 9 | | name | The name of your cast | 10 | 11 | | Flags | Description | 12 | |----------|-------------------------| 13 | | --force | Overwrite existing file | 14 | -------------------------------------------------------------------------------- /docs/commands/make-collection.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:collection` 2 | Creates a new Laravel collection for a model. 3 | 4 | > [!NOTE] 5 | > You need to add the collection to your model 6 | > ```php 7 | > public function newCollection(array $models = []): Collection 8 | > { 9 | > return new UserCollection($models); 10 | > } 11 | > ``` 12 | 13 | ## Signature 14 | `beyond:make:collection {name} {--force}` 15 | 16 | | Parameters | Description | 17 | |------------|-----------------------------| 18 | | name | The name of your collection | 19 | 20 | | Flags | Description | 21 | |---------|-------------------------| 22 | | --force | Overwrite existing file | 23 | -------------------------------------------------------------------------------- /docs/commands/make-command.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:command` 2 | Creates a new Laravel command. 3 | 4 | > [!IMPORTANT] 5 | > You need to add your command with `Artisan::registerCommand(YourCommand::class)` inside `routes/console.php`. 6 | 7 | ## Signature 8 | `beyond:make:command {name} {--command=command:name} {--force}` 9 | 10 | | Parameters | Description | 11 | |------------|--------------------------| 12 | | name | The name of your command | 13 | 14 | | Flags | Description | 15 | |-----------|-------------------------| 16 | | --command | Define the command name | 17 | | --force | Overwrite existing file | 18 | -------------------------------------------------------------------------------- /docs/commands/make-controller.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:controller` 2 | Creates a new controller. 3 | 4 | ## Signature 5 | `beyond:make:controller {name} {--api} {--i|invokable} {--force}` 6 | 7 | | Parameters | Description | 8 | |------------|--------------------------| 9 | | name | The name of your command | 10 | 11 | | Flags | Description | 12 | |-------------|---------------------------------| 13 | | --api | Creates a resource controller | 14 | | --invokable | Creates an invokable controller | 15 | | --force | Overwrite existing file | 16 | -------------------------------------------------------------------------------- /docs/commands/make-data.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:data` 2 | Creates a new Spatie data transfer object. 3 | 4 | > [!IMPORTANT] 5 | > Requires package `spatie/laravel-data` 6 | 7 | ## Signature 8 | `beyond:make:data {name} {--force}` 9 | 10 | | Parameters | Description | 11 | |------------|---------------------------------------| 12 | | name | The name of your data transfer object | 13 | 14 | | Flags | Description | 15 | |---------|-------------------------| 16 | | --force | Overwrite existing file | 17 | -------------------------------------------------------------------------------- /docs/commands/make-enum.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:enum` 2 | Creates a new enum. 3 | 4 | ## Signature 5 | `beyond:make:enum {name} {--force}` 6 | 7 | | Parameters | Description | 8 | |------------|-----------------------| 9 | | name | The name of your enum | 10 | 11 | | Flags | Description | 12 | |---------|-------------------------| 13 | | --force | Overwrite existing file | 14 | -------------------------------------------------------------------------------- /docs/commands/make-event.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:event` 2 | Creates a new event. 3 | 4 | ## Signature 5 | `beyond:make:event {name} {--force}` 6 | 7 | | Parameters | Description | 8 | |------------|------------------------| 9 | | name | The name of your event | 10 | 11 | | Flags | Description | 12 | |---------|-------------------------| 13 | | --force | Overwrite existing file | 14 | -------------------------------------------------------------------------------- /docs/commands/make-job.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:job` 2 | Creates a new job. 3 | 4 | ## Signature 5 | `beyond:make:job {name} {--force}` 6 | 7 | | Parameters | Description | 8 | |------------|----------------------| 9 | | name | The name of your job | 10 | 11 | | Flags | Description | 12 | |---------|-------------------------| 13 | | --force | Overwrite existing file | 14 | -------------------------------------------------------------------------------- /docs/commands/make-listener.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:listener` 2 | Creates a new listener. 3 | 4 | ## Signature 5 | `beyond:make:listener {name} {--force}` 6 | 7 | | Parameters | Description | 8 | |------------|---------------------------| 9 | | name | The name of your listener | 10 | 11 | | Flags | Description | 12 | |---------|-------------------------| 13 | | --force | Overwrite existing file | 14 | -------------------------------------------------------------------------------- /docs/commands/make-model.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:model` 2 | Creates a new model. 3 | 4 | ## Signature 5 | `beyond:make:model {name} {--force}` 6 | 7 | | Parameters | Description | 8 | |------------|------------------------| 9 | | name | The name of your model | 10 | 11 | | Flags | Description | 12 | |---------|-------------------------| 13 | | --force | Overwrite existing file | 14 | -------------------------------------------------------------------------------- /docs/commands/make-observer.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:observer` 2 | Creates a new observer. 3 | 4 | ## Signature 5 | `beyond:make:observer {name} {--force}` 6 | 7 | | Parameters | Description | 8 | |------------|---------------------------| 9 | | name | The name of your observer | 10 | 11 | | Flags | Description | 12 | |---------|-------------------------| 13 | | --force | Overwrite existing file | 14 | -------------------------------------------------------------------------------- /docs/commands/make-policy.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:policy` 2 | Creates a new policy. 3 | 4 | > [!NOTE] 5 | > If you used the `beyond:publish:gate` command, all new policies will be created inside you applications. You can have 6 | > the same policy for every application. Use `Gate::app('{AppName}')` followed by your authorization method 7 | > (e.g. `Gate::app('Admin')->authorize('view', $user)`) to tell Laravel which application to search for the policy. 8 | > If no policy is found, it will fall back to Laravels default policy handling. 9 | 10 | ## Signature 11 | `beyond:make:policy {name} {--force}` 12 | 13 | | Parameters | Description | 14 | |------------|-------------------------| 15 | | name | The name of your policy | 16 | 17 | | Flags | Description | 18 | |---------|-------------------------| 19 | | --force | Overwrite existing file | 20 | -------------------------------------------------------------------------------- /docs/commands/make-process.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:process` 2 | Creates a new process. A process is made up of one or more actions and produces the desired 3 | result. A process for creating the user would look like this, for example: Validate the request, 4 | create the user, send an e-mail, send a notification to the administrator. This process is 5 | individual for each application, e.g. the process in the administration application could 6 | dispense with sending the notification to the administrator. 7 | 8 | ## Signature 9 | `beyond:make:process {name} {--force}` 10 | 11 | | Parameters | Description | 12 | |------------|--------------------------| 13 | | name | The name of your process | 14 | 15 | | Flags | Description | 16 | |---------|-------------------------| 17 | | --force | Overwrite existing file | 18 | -------------------------------------------------------------------------------- /docs/commands/make-provider.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:provider` 2 | Creates a new service provider. 3 | 4 | > [!NOTE] 5 | > Within the register method, you should **only bind things into the service container**. 6 | > Because of this, service providers are **not** created under `Application/{App}/Providers`. 7 | > We want to avoid the feeling of registering things per application. You always register things 8 | > for your entire Laravel project. 9 | 10 | ## Signature 11 | `beyond:make:provider {name} {--force}` 12 | 13 | | Parameters | Description | 14 | |------------|---------------------------| 15 | | name | The name of your provider | 16 | 17 | | Flags | Description | 18 | |----------|-------------------------| 19 | | --force | Overwrite existing file | 20 | -------------------------------------------------------------------------------- /docs/commands/make-query.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:query` 2 | Creates a new Spatie query builder. 3 | 4 | > [!IMPORTANT] 5 | > Requires package `spatie/laravel-query-builder` 6 | 7 | ## Signature 8 | `beyond:make:query {name} {--force}` 9 | 10 | | Parameters | Description | 11 | |------------|--------------------------------| 12 | | name | The name of your query builder | 13 | 14 | | Flags | Description | 15 | |---------|-------------------------| 16 | | --force | Overwrite existing file | 17 | -------------------------------------------------------------------------------- /docs/commands/make-request.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:request` 2 | Creates a new request. 3 | 4 | ## Signature 5 | `beyond:make:request {name} {--force}` 6 | 7 | | Parameters | Description | 8 | |------------|--------------------------| 9 | | name | The name of your request | 10 | 11 | | Flags | Description | 12 | |---------|-------------------------| 13 | | --force | Overwrite existing file | 14 | -------------------------------------------------------------------------------- /docs/commands/make-resource.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:resource` 2 | Creates a new resource. 3 | 4 | ## Signature 5 | `beyond:make:resource {name} {--force}` 6 | 7 | | Parameters | Description | 8 | |------------|---------------------------| 9 | | name | The name of your resource | 10 | 11 | | Flags | Description | 12 | |---------|-------------------------| 13 | | --force | Overwrite existing file | 14 | -------------------------------------------------------------------------------- /docs/commands/make-rule.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:rule` 2 | Creates a new rule. 3 | 4 | ## Signature 5 | `beyond:make:rule {name} {--force}` 6 | 7 | | Parameters | Description | 8 | |------------|-----------------------| 9 | | name | The name of your rule | 10 | 11 | | Flags | Description | 12 | |----------|-------------------------| 13 | | --force | Overwrite existing file | 14 | -------------------------------------------------------------------------------- /docs/commands/make-scope.md: -------------------------------------------------------------------------------- 1 | # `beyond:make:scope` 2 | Creates a new scope. 3 | 4 | ## Signature 5 | `beyond:make:scope {name} {--g|global} {--force}` 6 | 7 | | Parameters | Description | 8 | |------------|------------------------| 9 | | name | The name of your scope | 10 | 11 | | Flags | Description | 12 | |----------|-------------------------------------------| 13 | | --global | Creates the scope inside `Support\Scopes` | 14 | | --force | Overwrite existing file | 15 | -------------------------------------------------------------------------------- /docs/commands/publish-gate.md: -------------------------------------------------------------------------------- 1 | # `beyond:publish:gate` 2 | Publishes a custom Gate which allows you to use/create policies on applications. This can be useful if you have multiple 3 | applications which require specific authorization per application. 4 | 5 | > [!NOTE] 6 | > You need to add the `Support\\Beyond\\Gate` to your `AppServiceProvider`s `register` function: 7 | > ```php 8 | > use Illuminate\Contracts\Auth\Access\Gate as GateContract; 9 | > use Support\Beyond\Gate; 10 | > 11 | > $this->app->singleton(GateContract::class, function ($app) { 12 | > return new Gate($app, fn () => call_user_func($app['auth']->userResolver())); 13 | > }); 14 | > ``` 15 | 16 | ## Signature 17 | `beyond:publish:gate {--force}` 18 | 19 | | Flags | Description | 20 | |---------|-------------------------| 21 | | --force | Overwrite existing file | 22 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | parameters: 2 | level: 6 3 | paths: 4 | - src 5 | - tests -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ./tests 6 | 7 | 8 | 9 | 10 | 11 | ./src 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /pint.json: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "laravel", 3 | "rules": { 4 | "binary_operator_spaces": { 5 | "default": "single_space", 6 | "operators": { 7 | "=>": "align_single_space_minimal" 8 | } 9 | }, 10 | "no_unused_imports": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Actions/CopyAndRefactorDirectoryAction.php: -------------------------------------------------------------------------------- 1 | $refactor 15 | */ 16 | public function execute(string $sourcePath, string $targetPath, array $refactor = [], bool $force = false): void 17 | { 18 | $fs = new Filesystem; 19 | $files = $fs->files($sourcePath); 20 | 21 | foreach ($files as $file) { 22 | $this->copyAndRefactorFileAction->execute( 23 | $sourcePath.'/'.$file->getFilename(), 24 | $targetPath.'/'.$file->getFilename(), 25 | $refactor, 26 | $force 27 | ); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Actions/CopyAndRefactorFileAction.php: -------------------------------------------------------------------------------- 1 | $refactor 16 | * 17 | * @throws AlreadyExistsException 18 | */ 19 | public function execute(string $sourcePath, string $targetPath, array $refactor = [], bool $force = false): void 20 | { 21 | $this->copyFileAction->execute($sourcePath, $targetPath, $force); 22 | 23 | if ($refactor) { 24 | $this->refactorFileAction->execute($targetPath, $refactor); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Actions/CopyDirectoryAction.php: -------------------------------------------------------------------------------- 1 | normalizePathAction->execute([ 17 | $srcPath, 18 | $targetPath, 19 | ]); 20 | 21 | $fs = new Filesystem; 22 | 23 | if (! $force && $fs->exists($targetPath)) { 24 | throw new AlreadyExistsException('Directory already exists. You could use --force to create a new file.'); 25 | } 26 | 27 | $fs->copyDirectory( 28 | $srcPath, 29 | $targetPath 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Actions/CopyFileAction.php: -------------------------------------------------------------------------------- 1 | normalizePathAction->execute([ 17 | $srcPath, 18 | $targetPath, 19 | ]); 20 | 21 | $fs = new Filesystem; 22 | 23 | $fs->ensureDirectoryExists( 24 | dirname($targetPath), 25 | ); 26 | 27 | if (! $force && $fs->exists($targetPath)) { 28 | throw new AlreadyExistsException('File already exists. You could use --force to create a new file.'); 29 | } 30 | 31 | $fs->copy( 32 | $srcPath, 33 | $targetPath, 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Actions/CreateDirectoryAction.php: -------------------------------------------------------------------------------- 1 | $directory 15 | */ 16 | public function execute(string|array $directory): void 17 | { 18 | if (is_array($directory)) { 19 | foreach ($directory as $dir) { 20 | $this->execute($dir); 21 | } 22 | 23 | return; 24 | } 25 | 26 | (new Filesystem)->ensureDirectoryExists( 27 | $this->normalizePathAction->execute(base_path('modules/'.$directory)) 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Actions/CreateFileAction.php: -------------------------------------------------------------------------------- 1 | |array $files 16 | */ 17 | public function execute(string|array $files): void 18 | { 19 | $fs = new Filesystem; 20 | $files = Arr::wrap($files); 21 | 22 | foreach ($files as $file => $contents) { 23 | if (is_int($file)) { 24 | $file = $contents; 25 | $contents = ''; 26 | } 27 | 28 | $file = $this->normalizePathAction->execute($file); 29 | 30 | $fs->ensureDirectoryExists(dirname($file)); 31 | 32 | $fs->put($file, $contents); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Actions/DeletePathAction.php: -------------------------------------------------------------------------------- 1 | normalizePathAction->execute($path); 16 | 17 | $fs = new Filesystem; 18 | 19 | if ($fs->isDirectory($path)) { 20 | $fs->deleteDirectory($path); 21 | } else { 22 | $fs->delete($path); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Actions/MoveAndRefactorFileAction.php: -------------------------------------------------------------------------------- 1 | $refactor 14 | */ 15 | public function execute(string $sourcePath, string $targetPath, array $refactor = [], bool $force = false): void 16 | { 17 | $this->moveFileAction->execute($sourcePath, $targetPath, $force); 18 | 19 | if ($refactor) { 20 | $this->refactorFileAction->execute($targetPath, $refactor); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Actions/MoveFileAction.php: -------------------------------------------------------------------------------- 1 | normalizePathAction->execute([ 16 | $sourcePath, 17 | $targetPath, 18 | ]); 19 | 20 | $fs = new Filesystem; 21 | 22 | $fs->ensureDirectoryExists(dirname($targetPath)); 23 | 24 | if (! $force && $fs->exists($targetPath)) { 25 | throw new \Exception('File already exists'); // TODO: Custom Exception 26 | } 27 | 28 | $fs->move( 29 | $sourcePath, 30 | $targetPath 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Actions/NormalizePathAction.php: -------------------------------------------------------------------------------- 1 | |string $path 12 | * @return array|string 13 | */ 14 | public function execute(array|string $path): array|string 15 | { 16 | $single = is_string($path); 17 | $paths = Arr::wrap($path); 18 | 19 | foreach ($paths as $k => $p) { 20 | $paths[$k] = Str::replace('/', DIRECTORY_SEPARATOR, $p); 21 | } 22 | 23 | if ($single) { 24 | return array_pop($paths); 25 | } 26 | 27 | return $paths; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Actions/RefactorFileAction.php: -------------------------------------------------------------------------------- 1 | $refactor 9 | */ 10 | public function execute(string $path, array $refactor): void 11 | { 12 | if (! $contents = file_get_contents($path)) { 13 | return; 14 | } 15 | 16 | file_put_contents( 17 | $path, 18 | str_replace( 19 | array_keys($refactor), 20 | $refactor, 21 | $contents 22 | ) 23 | ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Affiliation.php: -------------------------------------------------------------------------------- 1 | $this->value.'\\%s\\%s', 15 | self::SUPPORT => $this->value.'\\%s', 16 | }; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Commands/Abstracts/ApplicationCommand.php: -------------------------------------------------------------------------------- 1 | */ 17 | private array $placeholders = []; 18 | 19 | /** @var array */ 20 | private array $onSuccess = []; 21 | 22 | /** @var array */ 23 | protected $aliases = []; 24 | 25 | abstract protected function getStub(): string; 26 | 27 | abstract public function getAffiliation(): Affiliation; 28 | 29 | abstract public function getType(): Type; 30 | 31 | public function getNamespaceTemplate(): string 32 | { 33 | return $this->getAffiliation()->toNamespaceTemplate(); 34 | } 35 | 36 | public function getFileNameTemplate(): string 37 | { 38 | return '%s.php'; 39 | } 40 | 41 | protected function addOnSuccess(callable $callback): void 42 | { 43 | $this->onSuccess[] = $callback; 44 | } 45 | 46 | /** 47 | * @param array $array 48 | */ 49 | protected function mergePlaceholders(array $array): void 50 | { 51 | $this->placeholders = array_merge( 52 | $this->placeholders, 53 | $array 54 | ); 55 | } 56 | 57 | protected function getNameArgument(): string 58 | { 59 | return trim($this->argument('name')); 60 | } 61 | 62 | public function getNameResolver(?string $name = null): NameResolver 63 | { 64 | return new NameResolver($this, new Stringable($name ?: $this->getNameArgument())); 65 | } 66 | 67 | protected function configure(): void 68 | { 69 | $this->setAliases($this->aliases); 70 | 71 | parent::configure(); 72 | } 73 | 74 | public function handle(): void 75 | { 76 | try { 77 | $fqn = $this->getNameResolver(); 78 | 79 | if (method_exists($this, 'setup')) { 80 | $this->setup($fqn); 81 | } 82 | 83 | $refactor = array_merge( 84 | [ 85 | '{{ namespace }}' => $fqn->getNamespace(), 86 | '{{ className }}' => $fqn->getClassName(), 87 | ], 88 | $this->placeholders 89 | ); 90 | 91 | beyond_copy_stub( 92 | $this->getStub(), 93 | beyond_path($fqn->getPath()), 94 | $refactor, 95 | $this->hasOption('force') ? (bool) $this->option('force') : false 96 | ); 97 | 98 | info($this->getType()->getName()." [{$fqn->getPath()}] created successfully."); 99 | 100 | foreach ($this->onSuccess as $callback) { 101 | $callback($fqn->getNamespace(), $fqn->getClassName()); 102 | } 103 | } catch (\Exception $exception) { 104 | error($exception->getMessage()); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/Commands/Abstracts/DomainCommand.php: -------------------------------------------------------------------------------- 1 | addOnSuccess(function (string $namespace, string $className) { 31 | info('Please add following code to your related model:'); 32 | note('public function newEloquentBuilder($query)'.PHP_EOL.'{'.PHP_EOL."\t".'return new '.$className.'($query);'.PHP_EOL.'}'); 33 | }); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Commands/MakeCastCommand.php: -------------------------------------------------------------------------------- 1 | mergePlaceholders([ 27 | '{{ command }}' => $this->option('command'), 28 | ]); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Commands/MakeControllerCommand.php: -------------------------------------------------------------------------------- 1 | option('api'); 17 | $invokable = $this->option('invokable'); 18 | 19 | return match (true) { 20 | $api && ! $invokable => 'controller.api.stub', 21 | $invokable && ! $api => 'controller.invokable.stub', 22 | default => 'controller.stub' 23 | }; 24 | } 25 | 26 | public function getType(): Type 27 | { 28 | return new Type('Controller'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Commands/MakeDataTransferObjectCommand.php: -------------------------------------------------------------------------------- 1 | */ 13 | protected $aliases = [ 14 | 'beyond:make:dto', 15 | ]; 16 | 17 | protected $description = 'Make a new data transfer object'; 18 | 19 | protected function getStub(): string 20 | { 21 | return 'data-transfer-object.stub'; 22 | } 23 | 24 | public function getType(): Type 25 | { 26 | return new Type('DataObject'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Commands/MakeEnumCommand.php: -------------------------------------------------------------------------------- 1 | option('sync') => 'job.sync.stub', 18 | default => 'job.stub' 19 | }; 20 | } 21 | 22 | public function getType(): Type 23 | { 24 | return new Type('Job'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Commands/MakeListenerCommand.php: -------------------------------------------------------------------------------- 1 | option('collection') 17 | ? 'resoource.collection.stub' 18 | : 'resource.stub'; 19 | } 20 | 21 | public function getType(): Type 22 | { 23 | return new Type('Resource'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Commands/MakeRuleCommand.php: -------------------------------------------------------------------------------- 1 | app->runningInConsole()) { 13 | $this->commands(...$this->beyondCommands()); 14 | } 15 | } 16 | 17 | /** 18 | * @return array 19 | */ 20 | public function beyondCommands(): array 21 | { 22 | $exclude = []; 23 | 24 | $fs = new Filesystem; 25 | $files = $fs->files(__DIR__.DIRECTORY_SEPARATOR.'Commands'); 26 | 27 | return array_map( 28 | fn ($file) => 'AkrilliA\\LaravelBeyond\\Commands\\'.$file->getBasename('.php'), 29 | array_filter( 30 | $files, 31 | fn ($file) => ! in_array($file->getBasename('.php'), $exclude, true) // @phpstan-ignore-line 32 | ) 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/NameResolver.php: -------------------------------------------------------------------------------- 1 | setAppOrDomain($this->name); 29 | $this->setDirectoryAndClassName($this->name->after('.')); 30 | $this->setNamespace(); 31 | $this->setPath(); 32 | } 33 | 34 | public function getNamespace(): string 35 | { 36 | return $this->namespace; 37 | } 38 | 39 | public function getClassName(): string 40 | { 41 | return $this->className; 42 | } 43 | 44 | public function getPath(): string 45 | { 46 | return $this->path; 47 | } 48 | 49 | private function isGlobal(): bool 50 | { 51 | return $this->command instanceof SupportCommand 52 | || ($this->command->hasOption('global') && $this->command->option('global')); 53 | } 54 | 55 | private function setAppOrDomain(Stringable $name): void 56 | { 57 | $this->appOrDomain = $name->contains('.') 58 | ? $name->before('.')->toString() 59 | : null; 60 | 61 | if ($this->appOrDomain || $this->isGlobal()) { 62 | return; 63 | } 64 | 65 | $cases = match ($this->command->getAffiliation()) { 66 | Affiliation::APPLICATION => ['app', beyond_get_choices(base_path('src/Application'))], 67 | Affiliation::DOMAIN => ['domain', beyond_get_choices(base_path('src/Domain'))], 68 | default => [] 69 | }; 70 | 71 | $this->appOrDomain = suggest( 72 | sprintf('On which %s do you want to add your %s', $cases[0], $this->command->getType()->getName()), 73 | function (string $value) use ($cases) { 74 | return collect($cases[1])->filter(fn ($o) => Str::contains($o, $value, true))->toArray(); 75 | }); 76 | } 77 | 78 | private function setDirectoryAndClassName(Stringable $name): void 79 | { 80 | $this->directory = $name->contains('/') 81 | ? $name->beforeLast('/')->replace('/', '\\')->toString() 82 | : ''; 83 | $this->className = $name->afterLast('/')->toString(); 84 | } 85 | 86 | private function setNamespace(): void 87 | { 88 | if ($this->isGlobal()) { 89 | $this->namespace = sprintf( 90 | 'Support\\%s%s', 91 | $this->command->getType()->getNamespace(), 92 | $this->directory ? '\\'.$this->directory : '', 93 | ); 94 | } else { 95 | $this->namespace = sprintf( 96 | $this->command->getNamespaceTemplate().'%s', 97 | $this->appOrDomain, 98 | $this->command->getType()->getNamespace(), 99 | $this->directory ? '\\'.$this->directory : '', 100 | ); 101 | } 102 | } 103 | 104 | private function setPath(): void 105 | { 106 | $this->path = sprintf( 107 | '%s/'.$this->command->getFileNameTemplate(), 108 | Str::ucfirst(Str::replace('\\', '/', $this->namespace)), 109 | $this->className, 110 | ); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/Type.php: -------------------------------------------------------------------------------- 1 | type; 18 | } 19 | 20 | public function getName(): string 21 | { 22 | return $this->name ?? Str::afterLast(Str::studly($this->type), DIRECTORY_SEPARATOR); 23 | } 24 | 25 | public function getNamespace(): string 26 | { 27 | return $this->namespace ?? Str::pluralStudly($this->type); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/helper.php: -------------------------------------------------------------------------------- 1 | $refactor 42 | */ 43 | function beyond_copy_stub(string $stub, string $path, array $refactor = [], bool $force = false): void 44 | { 45 | $stub = file_exists($stubPath = base_path('stubs/beyond.'.$stub)) 46 | ? $stubPath 47 | : __DIR__.'/../stubs/'.$stub; 48 | 49 | $action = new CopyAndRefactorFileAction( 50 | new CopyFileAction(new NormalizePathAction), 51 | new RefactorFileAction 52 | ); 53 | 54 | $action->execute( 55 | $stub, 56 | $path, 57 | $refactor, 58 | $force 59 | ); 60 | } 61 | } 62 | 63 | if (! function_exists('beyond_get_choices')) { 64 | /** 65 | * @return array 66 | */ 67 | function beyond_get_choices(string $path): array 68 | { 69 | $fs = new Filesystem; 70 | 71 | $fs->ensureDirectoryExists($path); 72 | 73 | return array_map( 74 | function ($directory) { 75 | return last(explode(DIRECTORY_SEPARATOR, $directory)); 76 | }, 77 | $fs->directories($path) 78 | ); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /stubs/action.stub: -------------------------------------------------------------------------------- 1 | app = $app; 16 | 17 | return $this; 18 | } 19 | 20 | protected function guessPolicyName($class): array 21 | { 22 | if ($this->guessPolicyNamesUsingCallback) { 23 | return Arr::wrap(call_user_func($this->guessPolicyNamesUsingCallback, $class, $this->app)); 24 | } 25 | 26 | if ($this->app) { 27 | $namespace = 'Application\\%s\\Policies\\%sPolicy'; 28 | $policyClass = sprintf( 29 | $namespace, 30 | $this->app, 31 | basename(str_replace('\\', '/', $class)) 32 | ); 33 | 34 | if (class_exists($policyClass)) { 35 | return [$policyClass]; 36 | } 37 | } 38 | 39 | $classDirname = str_replace('/', '\\', dirname(str_replace('\\', '/', $class))); 40 | 41 | $classDirnameSegments = explode('\\', $classDirname); 42 | 43 | return Arr::wrap(Collection::times(count($classDirnameSegments), function ($index) use ($class, $classDirnameSegments) { 44 | $classDirname = implode('\\', array_slice($classDirnameSegments, 0, $index)); 45 | 46 | return $classDirname.'\\Policies\\'.class_basename($class).'Policy'; 47 | })->reverse()->values()->first(function ($class) { 48 | return class_exists($class); 49 | }) ?: [$classDirname.'\\Policies\\'.class_basename($class).'Policy']); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /stubs/builder.stub: -------------------------------------------------------------------------------- 1 | $attributes 12 | */ 13 | public function get(Model $model, string $key, mixed $value, array $attributes): mixed 14 | { 15 | return $value; 16 | } 17 | 18 | /** 19 | * @param array $attributes 20 | */ 21 | public function set(Model $model, string $key, mixed $value, array $attributes): mixed 22 | { 23 | return $value; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /stubs/collection.plain.stub: -------------------------------------------------------------------------------- 1 | |string> 12 | */ 13 | public function rules(): array 14 | { 15 | return [ 16 | // 17 | ]; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /stubs/resource.collection.stub: -------------------------------------------------------------------------------- 1 | 12 | */ 13 | public function toArray(Request $request): array 14 | { 15 | return parent::toArray($request); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /stubs/resource.stub: -------------------------------------------------------------------------------- 1 | 12 | */ 13 | public function toArray(Request $request): array 14 | { 15 | return parent::toArray($request); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /stubs/rule.stub: -------------------------------------------------------------------------------- 1 | assertEquals(base_path('src'), beyond_path()); 10 | $this->assertEquals(beyond_path('Application'), beyond_app_path()); 11 | $this->assertEquals(beyond_path('Domain'), beyond_domain_path()); 12 | $this->assertEquals(beyond_path('Support'), beyond_support_path()); 13 | } 14 | 15 | public function test_can_make_class_with_directory(): void 16 | { 17 | $this->artisan('beyond:make:action User.Admin/UserStoreAction'); 18 | 19 | $file = beyond_domain_path('User/Actions/Admin/UserStoreAction.php'); 20 | $contents = file_get_contents($file); 21 | 22 | $this->assertFileExists($file); 23 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 24 | $this->assertStringNotContainsString('{{ className }}', $contents); 25 | } 26 | 27 | public function test_can_make_class_with_deep_directory(): void 28 | { 29 | $this->artisan('beyond:make:action User.Admin/SuperAdmin/UserStoreAction'); 30 | 31 | $file = beyond_domain_path('User/Actions/Admin/SuperAdmin/UserStoreAction.php'); 32 | $contents = file_get_contents($file); 33 | 34 | $this->assertFileExists($file); 35 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 36 | $this->assertStringNotContainsString('{{ className }}', $contents); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/Commands/MakeActionCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:action User.UserStoreAction'); 12 | 13 | $file = beyond_domain_path('User/Actions/UserStoreAction.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 18 | $this->assertStringNotContainsString('{{ className }}', $contents); 19 | } 20 | 21 | public function test_can_make_action_using_force(): void 22 | { 23 | $this->artisan('beyond:make:action User.UserStoreAction'); 24 | 25 | $file = beyond_domain_path('User/Actions/UserStoreAction.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 30 | $this->assertStringNotContainsString('{{ className }}', $contents); 31 | 32 | $code = $this->artisan('beyond:make:action User.UserStoreAction --force'); 33 | 34 | $code->assertOk(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Commands/MakeAdrActionCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:adr-action User.StoreUserAction'); 12 | 13 | $file = beyond_app_path('User/Actions/StoreUserAction.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 18 | $this->assertStringNotContainsString('{{ className }}', $contents); 19 | $this->assertStringContainsString('__invoke()', $contents); 20 | } 21 | 22 | public function test_can_make_adr_action_using_force(): void 23 | { 24 | $this->artisan('beyond:make:adr-action User.StoreUserAction'); 25 | 26 | $file = beyond_app_path('User/Actions/StoreUserAction.php'); 27 | $contents = file_get_contents($file); 28 | 29 | $this->assertFileExists($file); 30 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 31 | $this->assertStringNotContainsString('{{ className }}', $contents); 32 | $this->assertStringContainsString('__invoke()', $contents); 33 | 34 | $code = $this->artisan('beyond:make:adr-action User.StoreUserAction --force'); 35 | 36 | $code->assertOk(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/Commands/MakeBuilderCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:builder User.UserBuilder'); 12 | 13 | $file = beyond_domain_path('User/Builders/UserBuilder.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 18 | $this->assertStringNotContainsString('{{ className }}', $contents); 19 | } 20 | 21 | public function test_can_make_builder_using_force(): void 22 | { 23 | $this->artisan('beyond:make:builder User.UserBuilder'); 24 | 25 | $file = beyond_domain_path('User/Builders/UserBuilder.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 30 | $this->assertStringNotContainsString('{{ className }}', $contents); 31 | 32 | $code = $this->artisan('beyond:make:builder User.UserBuilder --force'); 33 | 34 | $code->assertOk(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Commands/MakeCastCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:cast TimezoneCast'); 12 | 13 | $file = beyond_support_path('Casts/TimezoneCast.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertNamespace('Support\\Casts', $contents); 18 | $this->assertClassName('TimezoneCast', $contents); 19 | } 20 | 21 | public function test_can_make_cast_using_force(): void 22 | { 23 | $this->artisan('beyond:make:cast TimezoneCast'); 24 | 25 | $file = beyond_support_path('Casts/TimezoneCast.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertNamespace('Support\\Casts', $contents); 30 | $this->assertClassName('TimezoneCast', $contents); 31 | 32 | $code = $this->artisan('beyond:make:cast TimezoneCast --force'); 33 | 34 | $code->assertOk(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Commands/MakeCollectionCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:collection User.UserCollection'); 12 | 13 | $file = beyond_domain_path('User/Collections/UserCollection.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 18 | $this->assertStringNotContainsString('{{ className }}', $contents); 19 | } 20 | 21 | public function test_can_make_collection_using_force(): void 22 | { 23 | $this->artisan('beyond:make:collection User.UserCollection'); 24 | 25 | $file = beyond_domain_path('User/Collections/UserCollection.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 30 | $this->assertStringNotContainsString('{{ className }}', $contents); 31 | 32 | $code = $this->artisan('beyond:make:collection User.UserCollection --force'); 33 | 34 | $code->assertOk(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Commands/MakeCommandCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:command User.CreateUser'); 12 | 13 | $file = beyond_app_path('User/Commands/CreateUser.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 18 | $this->assertStringNotContainsString('{{ className }}', $contents); 19 | } 20 | 21 | public function test_can_make_command_using_force(): void 22 | { 23 | $this->artisan('beyond:make:command User.CreateUser'); 24 | 25 | $file = beyond_app_path('User/Commands/CreateUser.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 30 | $this->assertStringNotContainsString('{{ className }}', $contents); 31 | 32 | $code = $this->artisan('beyond:make:command User.CreateUser --force'); 33 | $code->assertOk(); 34 | } 35 | 36 | public function test_can_make_command_with_predefined_signature(): void 37 | { 38 | $this->artisan('beyond:make:command User.CreateUser --command=test:execute'); 39 | 40 | $file = beyond_app_path('User/Commands/CreateUser.php'); 41 | $contents = file_get_contents($file); 42 | 43 | $this->assertFileExists($file); 44 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 45 | $this->assertStringNotContainsString('{{ className }}', $contents); 46 | $this->assertStringContainsString('test:execute', $contents); 47 | } 48 | 49 | public function test_can_make_command_with_predefined_signature_using_force(): void 50 | { 51 | $this->artisan('beyond:make:command User.CreateUser --command=test:execute'); 52 | 53 | $file = beyond_app_path('User/Commands/CreateUser.php'); 54 | $contents = file_get_contents($file); 55 | 56 | $this->assertFileExists($file); 57 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 58 | $this->assertStringNotContainsString('{{ className }}', $contents); 59 | $this->assertStringContainsString('test:execute', $contents); 60 | 61 | $code = $this->artisan('beyond:make:command User.CreateUser --command=test:execute --force'); 62 | $code->assertOk(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /tests/Commands/MakeControllerCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:controller User.UserController'); 12 | 13 | $file = beyond_app_path('User/Controllers/UserController.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 18 | $this->assertStringNotContainsString('{{ className }}', $contents); 19 | } 20 | 21 | public function test_can_make_controller_using_force(): void 22 | { 23 | $this->artisan('beyond:make:controller User.UserController'); 24 | 25 | $file = beyond_app_path('User/Controllers/UserController.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 30 | $this->assertStringNotContainsString('{{ className }}', $contents); 31 | 32 | $code = $this->artisan('beyond:make:controller User.UserController'); 33 | $code->assertOk(); 34 | } 35 | 36 | public function test_can_make_api_controller(): void 37 | { 38 | $this->artisan('beyond:make:controller User.UserController --api'); 39 | 40 | $file = beyond_app_path('User/Controllers/UserController.php'); 41 | $contents = file_get_contents($file); 42 | 43 | $this->assertFileExists($file); 44 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 45 | $this->assertStringNotContainsString('{{ className }}', $contents); 46 | 47 | $methods = ['index()', 'show()', 'store()', 'update()', 'destroy()']; 48 | 49 | foreach ($methods as $method) { 50 | $this->assertStringContainsString($method, $contents); 51 | } 52 | } 53 | 54 | public function test_can_make_api_controller_using_force(): void 55 | { 56 | $this->artisan('beyond:make:controller User.UserController --api'); 57 | 58 | $file = beyond_app_path('User/Controllers/UserController.php'); 59 | $contents = file_get_contents($file); 60 | 61 | $this->assertFileExists($file); 62 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 63 | $this->assertStringNotContainsString('{{ className }}', $contents); 64 | 65 | $methods = ['index()', 'show()', 'store()', 'update()', 'destroy()']; 66 | 67 | foreach ($methods as $method) { 68 | $this->assertStringContainsString($method, $contents); 69 | } 70 | 71 | $code = $this->artisan('beyond:make:controller User.UserController --api --force'); 72 | 73 | $code->assertOk(); 74 | } 75 | 76 | public function test_can_make_invokable_controller(): void 77 | { 78 | $this->artisan('beyond:make:controller User.UserController --invokable'); 79 | 80 | $file = beyond_app_path('User/Controllers/UserController.php'); 81 | $contents = file_get_contents($file); 82 | 83 | $this->assertFileExists($file); 84 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 85 | $this->assertStringNotContainsString('{{ className }}', $contents); 86 | $this->assertStringContainsString('__invoke()', $contents); 87 | } 88 | 89 | public function test_can_make_invokable_controller_using_force(): void 90 | { 91 | $this->artisan('beyond:make:controller User.UserController --invokable'); 92 | 93 | $file = beyond_app_path('User/Controllers/UserController.php'); 94 | $contents = file_get_contents($file); 95 | 96 | $this->assertFileExists($file); 97 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 98 | $this->assertStringNotContainsString('{{ className }}', $contents); 99 | $this->assertStringContainsString('__invoke()', $contents); 100 | 101 | $code = $this->artisan('beyond:make:controller User.UserController --invokable --force'); 102 | 103 | $code->assertOk(); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /tests/Commands/MakeDataTransferObjectCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:data User.UserData'); 12 | 13 | $file = beyond_domain_path('User/DataObjects/UserData.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 18 | $this->assertStringNotContainsString('{{ className }}', $contents); 19 | } 20 | 21 | public function test_can_make_data_transfer_object_using_force(): void 22 | { 23 | $this->artisan('beyond:make:data User.UserData'); 24 | 25 | $file = beyond_domain_path('User/DataObjects/UserData.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 30 | $this->assertStringNotContainsString('{{ className }}', $contents); 31 | 32 | $code = $this->artisan('beyond:make:data User.UserData --force'); 33 | 34 | $code->assertOk(); 35 | } 36 | 37 | public function test_can_make_data_transfer_with_alias_object(): void 38 | { 39 | $this->artisan('beyond:make:dto User.UserData'); 40 | 41 | $file = beyond_domain_path('User/DataObjects/UserData.php'); 42 | $contents = file_get_contents($file); 43 | 44 | $this->assertFileExists($file); 45 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 46 | $this->assertStringNotContainsString('{{ className }}', $contents); 47 | } 48 | 49 | public function test_can_make_data_transfer_with_alias_object_using_force(): void 50 | { 51 | $this->artisan('beyond:make:dto User.UserData'); 52 | 53 | $file = beyond_domain_path('User/DataObjects/UserData.php'); 54 | $contents = file_get_contents($file); 55 | 56 | $this->assertFileExists($file); 57 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 58 | $this->assertStringNotContainsString('{{ className }}', $contents); 59 | 60 | $code = $this->artisan('beyond:make:dto User.UserData --force'); 61 | 62 | $code->assertOk(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /tests/Commands/MakeEnumCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:enum User.UserType'); 12 | 13 | $file = beyond_domain_path('User/Enums/UserType.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 18 | $this->assertStringNotContainsString('{{ className }}', $contents); 19 | } 20 | 21 | public function test_can_make_enum_using_force(): void 22 | { 23 | $this->artisan('beyond:make:enum User.UserType'); 24 | 25 | $file = beyond_domain_path('User/Enums/UserType.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 30 | $this->assertStringNotContainsString('{{ className }}', $contents); 31 | 32 | $code = $this->artisan('beyond:make:enum User.UserType --force'); 33 | 34 | $code->assertOk(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Commands/MakeEventCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:event User.UserCreated'); 12 | 13 | $file = beyond_domain_path('User/Events/UserCreated.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 18 | $this->assertStringNotContainsString('{{ className }}', $contents); 19 | } 20 | 21 | public function test_can_make_event_using_force(): void 22 | { 23 | $this->artisan('beyond:make:event User.UserCreated'); 24 | 25 | $file = beyond_domain_path('User/Events/UserCreated.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 30 | $this->assertStringNotContainsString('{{ className }}', $contents); 31 | 32 | $code = $this->artisan('beyond:make:event User.UserCreated --force'); 33 | 34 | $code->assertOk(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Commands/MakeJobCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:job User.CancelTrials'); 12 | 13 | $file = beyond_app_path('User/Jobs/CancelTrials.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 18 | $this->assertStringNotContainsString('{{ className }}', $contents); 19 | $this->assertStringContainsString('use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;', $contents); 20 | } 21 | 22 | public function test_can_make_job_using_force(): void 23 | { 24 | $this->artisan('beyond:make:job User.CancelTrials'); 25 | 26 | $file = beyond_app_path('User/Jobs/CancelTrials.php'); 27 | $contents = file_get_contents($file); 28 | 29 | $this->assertFileExists($file); 30 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 31 | $this->assertStringNotContainsString('{{ className }}', $contents); 32 | $this->assertStringContainsString('use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;', $contents); 33 | 34 | $code = $this->artisan('beyond:make:job User.CancelTrials --force'); 35 | 36 | $code->assertOk(); 37 | } 38 | 39 | public function test_can_make_synced_job(): void 40 | { 41 | $this->artisan('beyond:make:job User.CancelTrials --sync'); 42 | 43 | $file = beyond_app_path('User/Jobs/CancelTrials.php'); 44 | $contents = file_get_contents($file); 45 | 46 | $this->assertFileExists($file); 47 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 48 | $this->assertStringNotContainsString('{{ className }}', $contents); 49 | $this->assertStringContainsString('use Dispatchable;', $contents); 50 | } 51 | 52 | public function test_can_make_synced_job_using_force(): void 53 | { 54 | $this->artisan('beyond:make:job User.CancelTrials --sync'); 55 | 56 | $file = beyond_app_path('User/Jobs/CancelTrials.php'); 57 | $contents = file_get_contents($file); 58 | 59 | $this->assertFileExists($file); 60 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 61 | $this->assertStringNotContainsString('{{ className }}', $contents); 62 | $this->assertStringContainsString('use Dispatchable;', $contents); 63 | 64 | $code = $this->artisan('beyond:make:job User.CancelTrials --sync --force'); 65 | 66 | $code->assertOk(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /tests/Commands/MakeListenerCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:listener User.SendShipmentNotification'); 12 | 13 | $file = beyond_domain_path('User/Listeners/SendShipmentNotification.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 18 | $this->assertStringNotContainsString('{{ className }}', $contents); 19 | } 20 | 21 | public function test_can_make_listener_using_force(): void 22 | { 23 | $this->artisan('beyond:make:listener User.SendShipmentNotification'); 24 | 25 | $file = beyond_domain_path('User/Listeners/SendShipmentNotification.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 30 | $this->assertStringNotContainsString('{{ className }}', $contents); 31 | 32 | $code = $this->artisan('beyond:make:listener User.SendShipmentNotification --force'); 33 | 34 | $code->assertOk(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Commands/MakeModelCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:model User.User'); 12 | 13 | $file = beyond_domain_path('User/Models/User.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 18 | $this->assertStringNotContainsString('{{ className }}', $contents); 19 | } 20 | 21 | public function test_can_make_model_using_force(): void 22 | { 23 | $this->artisan('beyond:make:model User.User'); 24 | 25 | $file = beyond_domain_path('User/Models/User.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 30 | $this->assertStringNotContainsString('{{ className }}', $contents); 31 | 32 | $code = $this->artisan('beyond:make:model User.User --force'); 33 | 34 | $code->assertOk(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Commands/MakeObserverCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:observer User.UserObserver'); 12 | 13 | $file = beyond_domain_path('User/Observers/UserObserver.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 18 | $this->assertStringNotContainsString('{{ className }}', $contents); 19 | } 20 | 21 | public function test_can_make_observer_using_force(): void 22 | { 23 | $this->artisan('beyond:make:observer User.UserObserver'); 24 | 25 | $file = beyond_domain_path('User/Observers/UserObserver.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 30 | $this->assertStringNotContainsString('{{ className }}', $contents); 31 | 32 | $code = $this->artisan('beyond:make:observer User.UserObserver'); 33 | 34 | $code->assertOk(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Commands/MakePolicyCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:policy User.UserPolicy'); 12 | 13 | $file = beyond_domain_path('User/Policies/UserPolicy.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertNamespace('Domain\\User\\Policies', $contents); 18 | $this->assertClassName('UserPolicy', $contents); 19 | } 20 | 21 | public function test_can_make_policy_using_force(): void 22 | { 23 | $this->artisan('beyond:make:policy User.UserPolicy'); 24 | 25 | $file = beyond_domain_path('User/Policies/UserPolicy.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertNamespace('Domain\\User\\Policies', $contents); 30 | $this->assertClassName('UserPolicy', $contents); 31 | 32 | $code = $this->artisan('beyond:make:policy User.UserPolicy --force'); 33 | 34 | $code->assertOk(); 35 | } 36 | 37 | public function test_can_make_app_policy_if_gate_published(): void 38 | { 39 | $this->artisan('beyond:publish:gate'); 40 | $this->artisan('beyond:make:policy User.UserPolicy'); 41 | 42 | $file = beyond_app_path('User/Policies/UserPolicy.php'); 43 | $contents = file_get_contents($file); 44 | 45 | $this->assertFileExists($file); 46 | $this->assertNamespace('Application\\User\\Policies', $contents); 47 | $this->assertClassName('UserPolicy', $contents); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tests/Commands/MakeProcessCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:process User.AdminStoreUserProcess'); 12 | 13 | $file = beyond_app_path('User/Processes/AdminStoreUserProcess.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 18 | $this->assertStringNotContainsString('{{ className }}', $contents); 19 | } 20 | 21 | public function test_can_make_action_using_force(): void 22 | { 23 | $this->artisan('beyond:make:process User.AdminStoreUserProcess'); 24 | 25 | $file = beyond_app_path('User/Processes/AdminStoreUserProcess.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 30 | $this->assertStringNotContainsString('{{ className }}', $contents); 31 | 32 | $code = $this->artisan('beyond:make:process User.AdminStoreUserProcess --force'); 33 | 34 | $code->assertOk(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Commands/MakeQueryCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:query User.IndexUserQuery'); 12 | 13 | $file = beyond_app_path('User/Queries/IndexUserQuery.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 18 | $this->assertStringNotContainsString('{{ className }}', $contents); 19 | } 20 | 21 | public function test_can_make_query_using_force(): void 22 | { 23 | $this->artisan('beyond:make:query User.IndexUserQuery'); 24 | 25 | $file = beyond_app_path('User/Queries/IndexUserQuery.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 30 | $this->assertStringNotContainsString('{{ className }}', $contents); 31 | 32 | $code = $this->artisan('beyond:make:query User.IndexUserQuery --force'); 33 | 34 | $code->assertOk(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Commands/MakeRequestCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:request User.StoreUserRequest'); 12 | 13 | $file = beyond_app_path('User/Requests/StoreUserRequest.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 18 | $this->assertStringNotContainsString('{{ className }}', $contents); 19 | } 20 | 21 | public function test_can_make_request_using_force(): void 22 | { 23 | $this->artisan('beyond:make:request User.StoreUserRequest'); 24 | 25 | $file = beyond_app_path('User/Requests/StoreUserRequest.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 30 | $this->assertStringNotContainsString('{{ className }}', $contents); 31 | 32 | $code = $this->artisan('beyond:make:request User.StoreUserRequest --force'); 33 | 34 | $code->assertOk(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Commands/MakeResourceCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:resource User.UserResource'); 12 | 13 | $file = beyond_app_path('User/Resources/UserResource.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 18 | $this->assertStringNotContainsString('{{ className }}', $contents); 19 | } 20 | 21 | public function test_can_make_resource_using_force(): void 22 | { 23 | $this->artisan('beyond:make:resource User.UserResource'); 24 | 25 | $file = beyond_app_path('User/Resources/UserResource.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 30 | $this->assertStringNotContainsString('{{ className }}', $contents); 31 | 32 | $code = $this->artisan('beyond:make:resource User.UserResource --force'); 33 | 34 | $code->assertOk(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Commands/MakeRuleCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:rule UniqueUser'); 12 | 13 | $file = beyond_support_path('Rules/UniqueUser.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertNamespace('Support\\Rules', $contents); 18 | $this->assertClassName('UniqueUser', $contents); 19 | } 20 | 21 | public function test_can_make_rule_using_force(): void 22 | { 23 | $this->artisan('beyond:make:rule User/UniqueUser'); 24 | 25 | $file = beyond_support_path('Rules/User/UniqueUser.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertNamespace('Support\\Rules\\User', $contents); 30 | $this->assertClassName('UniqueUser', $contents); 31 | 32 | $code = $this->artisan('beyond:make:rule User/UniqueUser --force'); 33 | 34 | $code->assertOk(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Commands/MakeScopeCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:scope User.ActiveScope'); 12 | 13 | $file = beyond_domain_path('User/Scopes/ActiveScope.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertNamespace('Domain\\User\\Scopes', $contents); 18 | $this->assertClassName('ActiveScope', $contents); 19 | } 20 | 21 | public function test_can_make_scope_using_force(): void 22 | { 23 | $this->artisan('beyond:make:scope User.ActiveScope'); 24 | 25 | $file = beyond_domain_path('User/Scopes/ActiveScope.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertNamespace('Domain\\User\\Scopes', $contents); 30 | $this->assertClassName('ActiveScope', $contents); 31 | 32 | $code = $this->artisan('beyond:make:scope User.ActiveScope --force'); 33 | 34 | $code->assertOk(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Commands/MakeServiceProviderCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:make:provider UserServiceProvider'); 12 | 13 | $file = beyond_support_path('Providers/UserServiceProvider.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertNamespace('Support\\Providers', $contents); 18 | $this->assertClassName('UserServiceProvider', $contents); 19 | } 20 | 21 | public function test_can_make_provider_using_force(): void 22 | { 23 | $this->artisan('beyond:make:provider UserServiceProvider'); 24 | 25 | $file = beyond_support_path('Providers/UserServiceProvider.php'); 26 | $contents = file_get_contents($file); 27 | 28 | $this->assertFileExists($file); 29 | $this->assertStringNotContainsString('{{ module }}', $contents); 30 | 31 | $code = $this->artisan('beyond:make:provider UserServiceProvider --force'); 32 | 33 | $code->assertOk(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/Commands/PublishBeyondGateCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('beyond:publish:gate'); 12 | 13 | $file = beyond_support_path('Beyond/Gate.php'); 14 | $contents = file_get_contents($file); 15 | 16 | $this->assertFileExists($file); 17 | $this->assertNamespace('Support\\Beyond', $contents); 18 | $this->assertClassName('Gate', $contents); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | removeDirectory(beyond_path()); 22 | } 23 | 24 | private function removeDirectory(string $directory): void 25 | { 26 | if (! is_dir($directory)) { 27 | return; 28 | } 29 | 30 | if (! $handle = opendir($directory)) { 31 | return; 32 | } 33 | 34 | while (false !== $file = readdir($handle)) { 35 | if (! in_array($file, ['.', '..'], true)) { 36 | $path = $directory.DIRECTORY_SEPARATOR.$file; 37 | 38 | if (is_dir($path)) { 39 | $this->removeDirectory($path); 40 | } else { 41 | unlink($path); 42 | } 43 | } 44 | } 45 | 46 | closedir($handle); 47 | rmdir($directory); 48 | } 49 | 50 | protected function assertNamespace(string $namespace, string $contents): void 51 | { 52 | $this->assertStringNotContainsString('{{ namespace }}', $contents); 53 | $this->assertStringContainsString("namespace {$namespace};", $contents); 54 | } 55 | 56 | protected function assertClassName(string $className, string $contents): void 57 | { 58 | $this->assertStringNotContainsString('{{ className }}', $contents); 59 | $this->assertStringContainsString("class {$className}", $contents); 60 | } 61 | } 62 | --------------------------------------------------------------------------------