├── .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 | |  |  |
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 |
--------------------------------------------------------------------------------