├── .github ├── dependabot.yml ├── release-drafter.yml └── workflows │ ├── release-notes.yml │ └── tests.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── composer.json ├── config └── compass.php ├── docs ├── authenticator.md ├── configuration.md ├── documenter.md ├── installation.md └── introduction.md ├── package.json ├── public ├── app.css ├── app.js ├── favicon.ico ├── manifest.js ├── mix-manifest.json ├── vendor.js └── vendor.js.LICENSE.txt ├── resources ├── js │ ├── app.js │ ├── axios-instance.js │ ├── base.js │ ├── components │ │ ├── Alert.vue │ │ ├── CodeEditor.vue │ │ ├── ContentSpace.vue │ │ ├── DataTable.vue │ │ ├── Dropdown.vue │ │ ├── FilesInput.vue │ │ ├── HeaderFields.vue │ │ ├── HttpMethods.vue │ │ ├── HttpResponseSize.vue │ │ ├── HttpResponseTime.vue │ │ ├── HttpStatus.vue │ │ ├── Omnibox.vue │ │ ├── RequestTabs.vue │ │ ├── ResponseTabs.vue │ │ ├── SidebarMenu.vue │ │ ├── SiteHeader.vue │ │ ├── Spotlight.vue │ │ ├── request │ │ │ ├── AuthTab.vue │ │ │ ├── BodyTab.vue │ │ │ ├── DocsTab.vue │ │ │ ├── HeadersTab.vue │ │ │ ├── ParamsTab.vue │ │ │ ├── RouteTab.vue │ │ │ └── auth │ │ │ │ ├── Bearer.vue │ │ │ │ └── None.vue │ │ └── response │ │ │ ├── BodyTab.vue │ │ │ └── HeadersTab.vue │ ├── constants.js │ ├── pages │ │ ├── 404.vue │ │ ├── cortex.vue │ │ ├── example.vue │ │ └── welcome.vue │ └── routes.js ├── sass │ ├── _base.scss │ ├── _codemirror.scss │ ├── _modal.scss │ ├── _multiselect.scss │ ├── _spotlight.scss │ └── app.scss └── views │ ├── documenter │ └── documentarian │ │ ├── layout.blade.php │ │ └── partials │ │ ├── example-requests │ │ └── bash.blade.php │ │ ├── frontmatter.blade.php │ │ ├── info.blade.php │ │ └── route.blade.php │ └── layout.blade.php ├── src ├── Authenticator.php ├── Authenticators │ ├── CredentialResult.php │ ├── SanctumAuth.php │ ├── TokenAuth.php │ └── UserProvider.php ├── Compass.php ├── CompassServiceProvider.php ├── Console │ ├── BuildCommand.php │ ├── InstallCommand.php │ ├── PublishCommand.php │ └── RebuildCommand.php ├── Contracts │ ├── AuthenticatorRepository.php │ ├── DocumenterRepository.php │ ├── RequestRepository.php │ └── ResponseRepository.php ├── Documenter │ └── DocumentarianProvider.php ├── Http │ ├── Controllers │ │ ├── CredentialController.php │ │ ├── HomeController.php │ │ ├── RequestController.php │ │ └── ResponseController.php │ └── routes.php ├── RouteResult.php └── Storage │ ├── DatabaseRequestRepository.php │ ├── DatabaseResponseRepository.php │ ├── RouteModel.php │ ├── factories │ └── RouteModelFactory.php │ └── migrations │ └── 2019_08_08_100000_create_compass_routeables_table.php ├── tailwind.config.js ├── webpack.mix.js └── yarn.lock /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | 4 | # Maintain dependencies for npm. 5 | - package-ecosystem: npm 6 | directory: "/" 7 | schedule: 8 | interval: weekly 9 | labels: 10 | - dependencies 11 | versioning-strategy: increase 12 | rebase-strategy: disabled 13 | 14 | # Maintain dependencies for Composer. 15 | - package-ecosystem: composer 16 | directory: "/" 17 | schedule: 18 | interval: monthly 19 | labels: 20 | - dependencies 21 | versioning-strategy: increase-if-necessary 22 | rebase-strategy: disabled 23 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name-template: 'v$NEXT_MINOR_VERSION' 2 | tag-template: 'v$NEXT_MINOR_VERSION' 3 | exclude-labels: 4 | - 'skip-changelog' 5 | categories: 6 | - title: '🚀 Features' 7 | labels: 8 | - 'new-feature' 9 | - 'feature' 10 | - 'enhancement' 11 | - title: '🐛 Bug fixes' 12 | labels: 13 | - 'fix' 14 | - 'bugfix' 15 | - 'bug' 16 | - title: '📦 Dependencies' 17 | labels: 18 | - 'dependencies' 19 | change-template: '- $TITLE (#$NUMBER)' 20 | template: | 21 | ## Changes 22 | 23 | $CHANGES 24 | -------------------------------------------------------------------------------- /.github/workflows/release-notes.yml: -------------------------------------------------------------------------------- 1 | name: Release notes 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | update_release_draft: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: release-drafter/release-drafter@v5 13 | env: 14 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 15 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: tests 2 | 3 | on: 4 | push: 5 | pull_request: 6 | schedule: 7 | - cron: "0 0 * * *" 8 | 9 | jobs: 10 | tests: 11 | runs-on: ubuntu-latest 12 | 13 | strategy: 14 | fail-fast: true 15 | matrix: 16 | php: [7.3, 7.4, 8.0] 17 | laravel: [^6.0, ^7.0, ^8.0] 18 | 19 | name: P${{ matrix.php }} - L${{ matrix.laravel }} 20 | 21 | steps: 22 | - name: Checkout code 23 | uses: actions/checkout@v2 24 | 25 | - name: Cache dependencies 26 | uses: actions/cache@v2 27 | with: 28 | path: ~/.composer/cache/files 29 | key: dependencies-laravel-${{ matrix.laravel }}-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} 30 | 31 | - name: Setup PHP 32 | uses: shivammathur/setup-php@v2 33 | with: 34 | php-version: ${{ matrix.php }} 35 | extensions: dom, curl, libxml, mbstring, zip 36 | tools: composer:v2 37 | coverage: none 38 | 39 | - name: Install dependencies 40 | run: | 41 | composer require "illuminate/contracts=${{ matrix.laravel }}" --no-update 42 | composer update --prefer-dist --no-interaction --no-suggest 43 | 44 | - name: Execute tests 45 | run: vendor/bin/phpunit --verbose 46 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [Unreleased](https://github.com/davidhsianturi/laravel-compass/compare/v1.2.1...HEAD) 4 | 5 | ## [v1.2.1 (2021-06-13)](https://github.com/davidhsianturi/laravel-compass/compare/v1.2.0...v1.2.1) 6 | 7 | ## Changes 8 | 9 | - Allow host as a fallback domain when using variable domain ([#162](https://github.com/davidhsianturi/laravel-compass/pull/162)) 10 | 11 | ## [v1.2.0 (2021-01-12)](https://github.com/davidhsianturi/laravel-compass/compare/v1.1.1...v1.2.0) 12 | 13 | ## Changes 14 | 15 | - Make the example response body editable ([#123](https://github.com/davidhsianturi/laravel-compass/pull/123)) 16 | 17 | ## [v1.1.1 (2020-12-12)](https://github.com/davidhsianturi/laravel-compass/compare/v1.1.0...v1.1.1) 18 | 19 | ## Changes 20 | 21 | - PHP 8 support (#123) 22 | 23 | ## [v1.1.0 (2020-10-05)](https://github.com/davidhsianturi/laravel-compass/compare/v1.0.1...v1.1.0) 24 | 25 | ## Changes 26 | 27 | - Add Laravel 8 support ([#103](https://github.com/davidhsianturi/laravel-compass/pull/103)) 28 | - Update Tailwind config file ([#100](https://github.com/davidhsianturi/laravel-compass/pull/100)) 29 | - Adding release drafter action ([#84](https://github.com/davidhsianturi/laravel-compass/pull/84)) 30 | 31 | ## [v1.0.1 (2020-06-13)](https://github.com/davidhsianturi/laravel-compass/compare/v1.0.0...v1.0.1) 32 | 33 | ### Fixed 34 | - Testing fixes ([@4fb6ecc ](https://github.com/davidhsianturi/laravel-compass/commit/dd16971cb407500c3b65fdd58b04168b34f4f2a5)) 35 | 36 | ## [v1.0.0 (2020-04-03)](https://github.com/davidhsianturi/laravel-compass/compare/v0.6.0...v1.0.0) 37 | 38 | ### Added 39 | - Authenticator for auth requests ([#76](https://github.com/davidhsianturi/laravel-compass/pull/76)) 40 | - Laravel 7 support ([#71](https://github.com/davidhsianturi/laravel-compass/pull/71)) 41 | 42 | ### Changed 43 | - Revamped the UI ([#73](https://github.com/davidhsianturi/laravel-compass/pull/73)) 44 | - Change `ApiDocsRepository` to `DocumenterRepository` ([#79](https://github.com/davidhsianturi/laravel-compass/pull/79)) 45 | 46 | ### Removed 47 | - Dropped support for Laravel 5.8 48 | 49 | ## [v0.6.0 (2020-03-08)](https://github.com/davidhsianturi/laravel-compass/compare/v0.5.1...v0.6.0) 50 | 51 | ### Added 52 | - New request tab to manage query parameters ([#64 ](https://github.com/davidhsianturi/laravel-compass/pull/64)) 53 | - Add spotlight search to quickly find the endpoints ([#66 ](https://github.com/davidhsianturi/laravel-compass/pull/66)) 54 | 55 | ## [v0.5.0 (2020-02-22)](https://github.com/davidhsianturi/laravel-compass/compare/v0.4.1...v0.5.0) 56 | 57 | ### Added 58 | - Add response preview ([#57](https://github.com/davidhsianturi/laravel-compass/pull/57)) 59 | - Add auth tab components ([#59](https://github.com/davidhsianturi/laravel-compass/pull/59)) 60 | - Add default header ([@cadbac8](https://github.com/davidhsianturi/laravel-compass/commit/cadbac825efe8008ce212b1deefb4643b939383c)) 61 | 62 | ### Changed 63 | - Tidy up the front-end ([#60](https://github.com/davidhsianturi/laravel-compass/pull/60)) 64 | 65 | ## [v0.4.1 (2020-01-11)](https://github.com/davidhsianturi/laravel-compass/compare/v0.4.0...v0.4.1) 66 | 67 | ### Fixed 68 | - Fixed data-table for request header ([@a6bd01a](https://github.com/davidhsianturi/laravel-compass/commit/a6bd01ac27a31575f1130c5a3dfbcd4beb8a3d4a)) 69 | 70 | ## [v0.4.0 (2019-12-13)](https://github.com/davidhsianturi/laravel-compass/compare/v0.3.0...v0.4.0) 71 | 72 | ### Added 73 | - Add support for sub-domain routing ([#83d2541](https://github.com/davidhsianturi/laravel-compass/pull/53)) 74 | - New header select options component ([@8d6d5e8](https://github.com/davidhsianturi/laravel-compass/commit/7806673eb6108218524418b6c09cdc6757ba4f9e)) 75 | 76 | ### Changed 77 | - Removed forbidden header name from the suggestion list ([@c358263](https://github.com/davidhsianturi/laravel-compass/commit/8d6d5e86b4a2a8e796f3c87d3a20887bdffe684f)) 78 | - The selected method now saved to storage ([@33fbcce](https://github.com/davidhsianturi/laravel-compass/commit/6afadd081403e0127d49a9da7bf56ffb0c695c18)) 79 | - Use a selected method to the request list ([@0a322cd](https://github.com/davidhsianturi/laravel-compass/commit/ae5f2066ca92f9681390ff93d5d7e6afe6c76449)) 80 | - Dropped support for Laravel 5.7 ([@eb732c5](https://github.com/davidhsianturi/laravel-compass/commit/347a3bd7122ca44471523b80e6fa7570f9c061ba)) 81 | 82 | ### Fixed 83 | - Fix request body key type dropdown in Firefox ([@7806673](https://github.com/davidhsianturi/laravel-compass/commit/b80509753431ae38037778660dfa9b9fc81d4434)) 84 | 85 | ## [v0.3.0 (2019-11-25)](https://github.com/davidhsianturi/laravel-compass/compare/v0.2.0...v0.3.0) 86 | 87 | ### Added 88 | - Added more options to exclude the routes ([#40](https://github.com/davidhsianturi/laravel-compass/pull/40)) 89 | - Added form urlencoded & raw request body options ([#39](https://github.com/davidhsianturi/laravel-compass/pull/39)) 90 | 91 | ### Fixed 92 | - Fixed render HTTP response time and size components in `ResponseTabs.vue` ([71b7d38](https://github.com/davidhsianturi/laravel-compass/commit/71b7d3887f624e238043e22543cab21859bd4cfe)) 93 | 94 | ## [v0.2.0 (2019-11-08)](https://github.com/davidhsianturi/laravel-compass/compare/v0.1.1...v0.2.0) 95 | 96 | ### Added 97 | - Added HTTP methods component ([#26](https://github.com/davidhsianturi/laravel-compass/pull/26)) 98 | - Added HTTP status component ([#32](https://github.com/davidhsianturi/laravel-compass/pull/32)) 99 | - Added HTTP response size and timing component ([#35](https://github.com/davidhsianturi/laravel-compass/pull/35)) 100 | 101 | ## [v0.1.1 (2019-10-31)](https://github.com/davidhsianturi/laravel-compass/compare/v0.1.0...v0.1.1) 102 | 103 | ### Fixed 104 | - Fixed redirection route methods ([#12](https://github.com/davidhsianturi/laravel-compass/pull/12)) 105 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are **welcome** and will be fully **credited**. 4 | 5 | Please read and understand the contribution guide before creating an issue or pull request. 6 | 7 | ## Etiquette 8 | 9 | This project is open source, and as such, the maintainers give their free time to build and maintain the source code 10 | held within. They make the code freely available in the hope that it will be of use to other developers. It would be 11 | extremely unfair for them to suffer abuse or anger for their hard work. 12 | 13 | Please be considerate towards maintainers when raising issues or presenting pull requests. Let's show the 14 | world that developers are civilized and selfless people. 15 | 16 | It's the duty of the maintainer to ensure that all submissions to the project are of sufficient 17 | quality to benefit the project. Many developers have different skillsets, strengths, and weaknesses. Respect the maintainer's decision, and do not be upset or abusive if your submission is not used. 18 | 19 | ## Viability 20 | 21 | When requesting or submitting new features, first consider whether it might be useful to others. Open 22 | source projects are used by many developers, who may have entirely different needs to your own. Think about 23 | whether or not your feature is likely to be used by other users of the project. 24 | 25 | ## Procedure 26 | 27 | Before filing an issue: 28 | 29 | - Attempt to replicate the problem, to ensure that it wasn't a coincidental incident. 30 | - Check to make sure your feature suggestion isn't already present within the project. 31 | - Check the pull requests tab to ensure that the bug doesn't have a fix in progress. 32 | - Check the pull requests tab to ensure that the feature isn't already in progress. 33 | 34 | Before submitting a pull request: 35 | 36 | - Check the codebase to ensure that your feature doesn't already exist. 37 | - Check the pull requests to ensure that another person hasn't already submitted the feature or fix. 38 | 39 | ## Requirements 40 | 41 | If the project maintainer has any additional requirements, you will find them listed here. 42 | 43 | - **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](https://pear.php.net/package/PHP_CodeSniffer). 44 | 45 | - **Add tests!** - Your patch won't be accepted if it doesn't have tests. 46 | 47 | - **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date. 48 | 49 | - **Consider our release cycle** - We try to follow [SemVer v2.0.0](https://semver.org/). Randomly breaking public APIs is not an option. 50 | 51 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. 52 | 53 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](https://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting. 54 | 55 | **Happy coding**! 56 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) David H. Sianturi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | Build Status 5 | Total Downloads 6 | Latest Stable Version 7 | License 8 |

9 | 10 |

11 | 12 | 13 | 14 |

15 | 16 | ## Introduction 17 | 18 | Laravel Compass is an elegant REST assistant for the Laravel framework that you can use to test API calls and create API documentation. it provides automatically endpoints for GET, POST, PUT/PATCH, DELETE, various auth mechanisms, and other utility endpoints based on Laravel routes in your project. 19 | 20 | ## Installation and usage 21 | 22 | This package requires PHP 7.2 and Laravel 6.0 or higher. 23 | You'll find installation instructions and full documentation on https://davidhsianturi.com/laravel-compass. 24 | 25 | ## Changelog 26 | 27 | Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently. 28 | 29 | ## Contributing 30 | 31 | Please see [CONTRIBUTING](CONTRIBUTING.md) for details. 32 | 33 | ## License 34 | 35 | Laravel Compass is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). 36 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "davidhsianturi/laravel-compass", 3 | "description": "An elegant REST assistent for the Laravel framework.", 4 | "keywords": [ 5 | "laravel", 6 | "API", 7 | "testing", 8 | "documentation" 9 | ], 10 | "homepage": "https://github.com/davidhsianturi/laravel-compass", 11 | "license": "MIT", 12 | "authors": [{ 13 | "name": "David H. Sianturi", 14 | "email": "davidhsianturi@gmail.com" 15 | }], 16 | "require": { 17 | "php": "^7.3|^8.0", 18 | "illuminate/console": "^6.0|^7.0|^8.0", 19 | "illuminate/routing": "^6.0|^7.0|^8.0", 20 | "illuminate/support": "^6.0|^7.0|^8.0", 21 | "mpociot/documentarian": "dev-master" 22 | }, 23 | "require-dev": { 24 | "laravel/legacy-factories": "^1.0.5", 25 | "laravel/sanctum": "^2.0", 26 | "orchestra/testbench": "^4.0|^5.0|^6.0" 27 | }, 28 | "autoload": { 29 | "psr-4": { 30 | "Davidhsianturi\\Compass\\": "src/" 31 | } 32 | }, 33 | "autoload-dev": { 34 | "psr-4": { 35 | "Davidhsianturi\\Compass\\Tests\\": "tests/" 36 | } 37 | }, 38 | "extra": { 39 | "branch-alias": { 40 | "dev-master": "1.x-dev" 41 | }, 42 | "laravel": { 43 | "providers": [ 44 | "Davidhsianturi\\Compass\\CompassServiceProvider" 45 | ] 46 | } 47 | }, 48 | "config": { 49 | "sort-packages": true 50 | }, 51 | "minimum-stability": "dev", 52 | "prefer-stable": true 53 | } 54 | -------------------------------------------------------------------------------- /config/compass.php: -------------------------------------------------------------------------------- 1 | env('COMPASS_PATH', 'compass'), 16 | 17 | /* 18 | |-------------------------------------------------------------------------- 19 | | Laravel Routes 20 | |-------------------------------------------------------------------------- 21 | | 22 | | This is the routes rules that will be filtered for the requests list. 23 | | use "*" as a wildcard to match any characters. note that the following 24 | | array list "exclude" can be referenced by the route name or route URI. 25 | | "base_uri" is a string value as a comparison for grouping the routes. 26 | | 27 | */ 28 | 29 | 'routes' => [ 30 | 'domains' => [ 31 | '*', 32 | ], 33 | 34 | 'prefixes' => [ 35 | '*', 36 | ], 37 | 38 | 'exclude' => [ 39 | 'compass.*', 40 | 'debugbar.*', 41 | '_ignition/*', 42 | 'telescope/*', 43 | ], 44 | 45 | 'base_uri' => '*', 46 | ], 47 | 48 | /* 49 | |-------------------------------------------------------------------------- 50 | | Compass Storage Driver 51 | |-------------------------------------------------------------------------- 52 | | 53 | | This configuration options determines the storage driver that will 54 | | be used to store your API calls and routes. In addition, you may set any 55 | | custom options as needed by the particular driver you choose. 56 | | 57 | */ 58 | 59 | 'driver' => env('COMPASS_DRIVER', 'database'), 60 | 61 | 'storage' => [ 62 | 'database' => [ 63 | 'connection' => env('DB_CONNECTION', 'mysql'), 64 | ], 65 | ], 66 | 67 | /* 68 | |-------------------------------------------------------------------------- 69 | | Compass Authenticator 70 | |-------------------------------------------------------------------------- 71 | | 72 | | This options allow you to get all the "credentials" of users that you can 73 | | use to perform auth requests through the UI. when "enabled" set to "true" 74 | | you should adjust the authentication guard driver for your application to 75 | | support "token" or "sanctum". 76 | | 77 | */ 78 | 79 | 'authenticator' => [ 80 | 'enabled' => false, 81 | 'guard' => 'api', 82 | 'identifier' => 'email', 83 | ], 84 | 85 | /* 86 | |-------------------------------------------------------------------------- 87 | | Compass Documenter Provider 88 | |-------------------------------------------------------------------------- 89 | | 90 | | This configuration option determines the documenter provider that will be 91 | | used to create a beautiful API documentation. In addition, you may set 92 | | any custom options as needed by the particular provider you choose. 93 | | 94 | */ 95 | 96 | 'documenter' => 'documentarian', 97 | 98 | 'provider' => [ 99 | 'documentarian' => [ 100 | 'output' => 'public/docs', 101 | 'example_requests' => [ 102 | 'bash', 103 | ], 104 | ], 105 | ], 106 | ]; 107 | -------------------------------------------------------------------------------- /docs/authenticator.md: -------------------------------------------------------------------------------- 1 | # Authenticator 2 | 3 | Compass authenticator using [Laravel authentication](https://laravel.com/docs/7.x/authentication) guard driver to gather all the `credentials` of users automatically that can be used to perform auth requests through the UI. 4 | 5 | Currently, Compass ships with a simple based [Token](https://laravel.com/docs/6.x/api-authentication) guard driver and [Laravel Sanctum](https://laravel.com/docs/7.x/sanctum) guard driver; however, writing custom driver is simple and you are free to extend Compass Authenticator with your own guard implementations. 6 | 7 | You should enable Compass authenticator using the `enabled` configuration option: 8 | 9 | ```php 10 | 'authenticator' => [ 11 | 'enabled' => true, 12 | 'guard' => 'sanctum', 13 | ... 14 | ], 15 | ``` 16 | 17 | and you may adjust the authentication guard driver for your application to support `token` or `sanctum`. 18 | 19 | ### Custom Driver 20 | 21 | if one of the built-in Compass Authenticator guard driver doesn't fit your needs, you may write your own custom driver and register it with Compass. 22 | 23 | #### Writing The Driver 24 | 25 | Your driver should implements the `Davidhsianturi\Compass\Contracts\AuthenticatorRepository` interface class. This interface class contains only one method your custom driver must implement: 26 | 27 | ```php 28 | use Davidhsianturi\Compass\Contracts\AuthenticatorRepository; 29 | 30 | class JwtAuthenticator implements AuthenticatorRepository 31 | { 32 | /** 33 | * Return a valid credential of users. 34 | * 35 | * @return \Illuminate\Support\Collection|\Davidhsianturi\Compass\Authenticators\CredentialResult[] 36 | */ 37 | public function credentials() 38 | { 39 | ... 40 | } 41 | } 42 | ``` 43 | 44 | You may find it helpful to review the implementations of `credentials` method on the `Davidhsianturi\Compass\Authenticators\SanctumAuth` class. This class will provide you with a good starting point for learning how to implement the method in your own driver. 45 | 46 | 47 | #### Registering The Driver 48 | 49 | Once you have written your custom driver, you may register it with Compass using the `extend` method of the Compass authenticator. You should call the `extend` method from the `register` method of your `AppServiceProvider` or any other service provider used by your application. For example, if you have written a `JwtAuthenticator`, you may register it like so: 50 | 51 | ```php 52 | use Davidhsianturi\Compass\Authenticator; 53 | 54 | /** 55 | * Register any application services. 56 | * 57 | * @return void 58 | */ 59 | public function register() 60 | { 61 | if ($this->app->environment('local')) { 62 | $authenticator = $this->app->make(Authenticator::class); 63 | $authenticator->extend('jwt', function () use ($authenticator) { 64 | return new JwtAuthenticator($authenticator->getConfig()); 65 | }); 66 | } 67 | } 68 | ``` 69 | 70 | Once your driver has been registered, you may specify it as your default Compass authenticator guard in your `config/compass.php` configuration file: 71 | 72 | ```php 73 | 'authenticator' => [ 74 | 'enabled' => true, 75 | 'guard' => 'jwt', 76 | ... 77 | ], 78 | ``` 79 | -------------------------------------------------------------------------------- /docs/configuration.md: -------------------------------------------------------------------------------- 1 | # Configuration 2 | 3 | After publishing Compass's assets, its primary configuration file will be located at `config/compass.php` below is the default content of the config file: 4 | 5 | ```php 6 | return [ 7 | /* 8 | |-------------------------------------------------------------------------- 9 | | Compass Path 10 | |-------------------------------------------------------------------------- 11 | | 12 | | This is the URI path where Compass will be accessible from. Feel free 13 | | to change this path to anything you like. 14 | | 15 | */ 16 | 17 | 'path' => env('COMPASS_PATH', 'compass'), 18 | 19 | /* 20 | |-------------------------------------------------------------------------- 21 | | Laravel Routes 22 | |-------------------------------------------------------------------------- 23 | | 24 | | This is the routes rules that will be filtered for the requests list. use 25 | | * as a wildcard to match any characters. note that the following array 26 | | list "exclude" must be referenced by the route name. 27 | | "base_uri" is a string value as a comparison for grouping the routes. 28 | | 29 | */ 30 | 31 | 'routes' => [ 32 | 'domains' => [ 33 | '*', 34 | ], 35 | 36 | 'prefixes' => [ 37 | '*', 38 | ], 39 | 40 | 'exclude' => [ 41 | 'compass.*', 42 | 'debugbar.*', 43 | ], 44 | 45 | 'base_uri' => '*', 46 | ], 47 | 48 | /* 49 | |-------------------------------------------------------------------------- 50 | | Compass Storage Driver 51 | |-------------------------------------------------------------------------- 52 | | 53 | | This configuration options determines the storage driver that will 54 | | be used to store your API calls and routes. In addition, you may set any 55 | | custom options as needed by the particular driver you choose. 56 | | 57 | */ 58 | 59 | 'driver' => env('COMPASS_DRIVER', 'database'), 60 | 61 | 'storage' => [ 62 | 'database' => [ 63 | 'connection' => env('DB_CONNECTION', 'mysql'), 64 | ], 65 | ], 66 | 67 | /* 68 | |-------------------------------------------------------------------------- 69 | | Compass Authenticator 70 | |-------------------------------------------------------------------------- 71 | | 72 | | This options allow you to get all the "credentials" of users that you can 73 | | use to perform auth requests through the UI. when "enabled" set to "true" 74 | | you should adjust the authentication guard driver for your application to 75 | | support "token" or "sanctum". 76 | | 77 | */ 78 | 79 | 'authenticator' => [ 80 | 'enabled' => false, 81 | 'guard' => 'api', 82 | 'identifier' => 'email', 83 | ], 84 | 85 | /* 86 | |-------------------------------------------------------------------------- 87 | | Compass Documenter Provider 88 | |-------------------------------------------------------------------------- 89 | | 90 | | This configuration option determines the documenter provider that will be 91 | | used to create a beautiful API documentation. In addition, you may set 92 | | any custom options as needed by the particular provider you choose. 93 | | 94 | */ 95 | 96 | 'documenter' => 'documentarian', 97 | 98 | 'provider' => [ 99 | 'documentarian' => [ 100 | 'output' => 'public/docs', 101 | 'example_requests' => [ 102 | 'bash', 103 | ], 104 | ], 105 | ], 106 | ]; 107 | ``` 108 | 109 | ## Migration Customization 110 | 111 | If you are not going to use Compass's default migrations, you should call the `Compass::ignoreMigrations` method in the `register` method of your `AppServiceProvider`. 112 | You may export the default migrations using the `php artisan vendor:publish --tag=compass-migrations` command. 113 | -------------------------------------------------------------------------------- /docs/documenter.md: -------------------------------------------------------------------------------- 1 | # Documenter 2 | 3 | Compass documenter ships with [Documentarian](https://github.com/mpociot/documentarian) package by [Marcel Pociot](https://github.com/mpociot) that will be used to simply write beautiful API documentation. below is the example of how it looks like: 4 | 5 | ![Example of API documentation.](https://res.cloudinary.com/dave24hwj8/image/upload/v1585786513/example-of-api-documentation.png) 6 | 7 | Yes, Documentarian is a PHP port of the popular [Slate](https://github.com/slatedocs/slate) API documentation tool. 8 | 9 | ### Build Documentation 10 | 11 | When building documentation, you should run the `build` command: 12 | 13 | ```bash 14 | php artisan compass:build 15 | ``` 16 | 17 | Next, you should be able to visit the results at `yourproject.test/docs/index.html` in your browser. 18 | 19 | ### Rebuild Documentation 20 | 21 | You may rebuild documentation from existing markdown file, you should run the `rebuild` command: 22 | 23 | ```bash 24 | php artisan compass:rebuild 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/installation.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | Laravel Compass require **PHP 7.2 or higher** and **Laravel 6.0 or higher**. 4 | You may use Composer to install Compass into your Laravel project: 5 | 6 | ```bash 7 | composer require davidhsianturi/laravel-compass --dev 8 | ``` 9 | 10 | Once Composer is done, publish its assets using the `compass:install` Artisan command. After installing Compass, you should also run the `migrate` command: 11 | 12 | ```bash 13 | php artisan compass:install 14 | 15 | php artisan migrate 16 | ``` 17 | 18 | That's it! Next, you should be able to visit the Compass UI at `yourproject.test/compass` in your browser. 19 | 20 | ### Updating Compass 21 | 22 | When updating Compass, you should re-publish the assets: 23 | 24 | ```bash 25 | php artisan compass:publish 26 | ``` 27 | -------------------------------------------------------------------------------- /docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Laravel Compass is an elegant REST assistant for the Laravel framework that you can use to test API calls and create API documentation. it provides automatically endpoints for GET, POST, PUT/PATCH, DELETE, various auth mechanisms, and other utility endpoints based on Laravel routes in your project. 4 | 5 | ![Laravel Compass User Interface](https://res.cloudinary.com/dave24hwj8/image/upload/v1585775692/Screen_Shot_2020-04-02_at_16.05.24_PM.png) 6 | 7 |
8 | Build Status 9 | 10 | 11 | Laravel Compass Total Downloads 12 | 13 | 14 | 15 | Laravel Compass Latest Stable Version 16 | 17 | 18 | 19 | Laravel Compass License 20 | 21 | 22 |
23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "npm run development", 5 | "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 6 | "watch": "npm run development -- --watch", 7 | "watch-poll": "npm run watch -- --watch-poll", 8 | "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", 9 | "prod": "npm run production", 10 | "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" 11 | }, 12 | "devDependencies": { 13 | "axios": "^0.24", 14 | "cross-env": "^7.0", 15 | "laravel-mix": "^5.0.9", 16 | "resolve-url-loader": "^4.0.0", 17 | "sass-loader": "^12.3.0", 18 | "sass": "^1.43.5", 19 | "tailwindcss": "^1.9.4", 20 | "vue": "^2.6.14", 21 | "vue-codemirror": "^4.0.6", 22 | "vue-multiselect": "^2.1.6", 23 | "vue-router": "^3.5.3", 24 | "vue-template-compiler": "^2.6.14" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidhsianturi/laravel-compass/296f33c40e960b223b5cafc0bf48afb3fd4b2bee/public/favicon.ico -------------------------------------------------------------------------------- /public/manifest.js: -------------------------------------------------------------------------------- 1 | !function(e){function r(r){for(var n,l,f=r[0],i=r[1],a=r[2],c=0,s=[];c { 8 | config.timing = { 9 | start: performance.now(), 10 | end: null, 11 | duration: 0 12 | }; 13 | 14 | return config; 15 | }) 16 | 17 | instance.interceptors.response.use((response) => { 18 | response.config.timing.end = performance.now(); 19 | response.config.timing.duration = response.config.timing.end - response.config.timing.start; 20 | 21 | return response; 22 | }) 23 | 24 | export default instance; 25 | -------------------------------------------------------------------------------- /resources/js/base.js: -------------------------------------------------------------------------------- 1 | import qs from 'querystring'; 2 | import { REQUEST_BODY_OPTIONS } from './constants'; 3 | 4 | export default { 5 | data() { 6 | return { 7 | elementId: null, 8 | waitingTime: null, 9 | }; 10 | }, 11 | 12 | computed: { 13 | Compass() { 14 | return Compass; 15 | } 16 | }, 17 | 18 | methods: { 19 | /** 20 | * Show a success message. 21 | */ 22 | alertSuccess(message, autoClose) { 23 | this.$root.alert.mode = 'toast'; 24 | this.$root.alert.type = 'success'; 25 | this.$root.alert.message = message; 26 | this.$root.alert.autoClose = autoClose; 27 | }, 28 | 29 | /** 30 | * Show a confirmation dialog. 31 | */ 32 | alertConfirm(message, success, failure) { 33 | this.$root.alert.mode = 'dialog'; 34 | this.$root.alert.type = 'confirmation'; 35 | this.$root.alert.message = message; 36 | this.$root.alert.autoClose = false; 37 | this.$root.alert.confirmationCancel = failure; 38 | this.$root.alert.confirmationProceed = success; 39 | }, 40 | 41 | /** 42 | * Show an error message. 43 | */ 44 | alertError(message) { 45 | this.$root.alert.mode = 'dialog'; 46 | this.$root.alert.type = 'error'; 47 | this.$root.alert.message = message; 48 | this.$root.alert.autoClose = false; 49 | }, 50 | 51 | /** 52 | * The default entries for form request body. 53 | */ 54 | newFormRequests() { 55 | return [ 56 | { 57 | included: false, 58 | key: null, 59 | value: null, 60 | description: null, 61 | new: true, 62 | type: 'text', 63 | }, 64 | ]; 65 | }, 66 | 67 | /** 68 | * Filter form request body key/value pair. 69 | */ 70 | filterFormRequests(entries) { 71 | let arr = entries.filter(data => data.included == true); 72 | 73 | return arr.reduce((obj, item) => (obj[item.key] = item.value, obj), {}); 74 | }, 75 | 76 | /** 77 | * Append entries value and key to FormData object. 78 | */ 79 | toFormData(entries) { 80 | let data = this.filterFormRequests(entries); 81 | let formData = new FormData(); 82 | 83 | for (let pair in data) { 84 | formData.append(pair, data[pair]); 85 | } 86 | 87 | return formData; 88 | }, 89 | 90 | /** 91 | * Convert entries value and key to Form URL encoded string. 92 | * 93 | * @param {Array} entries 94 | * @param {String} 95 | */ 96 | toFormUrlEncoded(entries) { 97 | let data = this.filterFormRequests(entries); 98 | return qs.stringify(data); 99 | }, 100 | 101 | /** 102 | * Convert entries value and key to request data based on 'Content-Type'. 103 | * 104 | * @param {Array|String} entries 105 | * @param {String} contentType 106 | * @return {FormData|String} 107 | */ 108 | toRequestData(entries, contentType) { 109 | if (contentType === 'multipart/form-data') return this.toFormData(entries) 110 | if (contentType === 'application/x-www-form-urlencoded') return this.toFormUrlEncoded(entries) 111 | return entries 112 | }, 113 | 114 | /** 115 | * Normalize headers with the given auth. 116 | * 117 | * @param {Array} entries 118 | * @param {Object} auth 119 | * @return {Object} 120 | */ 121 | toRequestHeaders(entries, auth) { 122 | const authInStorage = localStorage.getItem(auth.key); 123 | const token = authInStorage ? JSON.parse(authInStorage).token : ''; 124 | const authHeader = { Authorization: `${auth.type} ${token}` }; 125 | const headers = this.filterFormRequests(entries); 126 | return auth.type === 'Bearer' ? { ...headers, ...authHeader } : headers; 127 | }, 128 | 129 | /** 130 | * The mouseOver/mouseOut event target in element. 131 | */ 132 | activateElmnt(val) { 133 | window.clearTimeout(this.waitingTime); 134 | 135 | this.waitingTime = window.setTimeout(() => { 136 | this.elementId = val; 137 | }, 100); 138 | }, 139 | 140 | /** 141 | * Normalize header 'Content-Type' into selected request body option. 142 | * 143 | * @param {String} contentType 144 | * @return {Object} 145 | */ 146 | normalizeContentType(contentType) { 147 | let bodyOption = { value: 'none', rawOption: 'text' } 148 | if (!contentType) return bodyOption 149 | 150 | let option = REQUEST_BODY_OPTIONS.find(opt => opt.value === contentType) 151 | bodyOption.value = option ? option.key : 'raw' 152 | 153 | if (bodyOption.value === 'raw') { 154 | option = REQUEST_BODY_OPTIONS.find(opt => opt.key === 'raw') 155 | const rawOption = option.options.find(opt => opt.value === contentType) 156 | bodyOption.rawOption = rawOption ? rawOption.key : 'text' 157 | } 158 | 159 | return bodyOption 160 | }, 161 | 162 | /** 163 | * Encode parameter entries to query string. 164 | * 165 | * @param {Array} entries 166 | * @param {String} uri 167 | */ 168 | encodeParams(entries, uri) { 169 | let query = this.toFormUrlEncoded(entries); 170 | let url = new URL(Compass.app.base_url.concat('/', uri)); 171 | url.search = query; 172 | let newUri = url.pathname + url.search; 173 | 174 | return decodeURI(newUri).slice(1); 175 | }, 176 | 177 | /** 178 | * Decode query string to parameter entries. 179 | * 180 | * @param {String} query 181 | */ 182 | decodeParams(query) { 183 | let newEntry = this.newFormRequests(); 184 | let url = new URL(Compass.app.base_url.concat('/', query)); 185 | let entries = [...url.searchParams.entries()].map(item => ( 186 | { ...newEntry[0], included: true, new: false, key: item[0], value: item[1] } 187 | )); 188 | 189 | return [...entries, ...newEntry]; 190 | } 191 | } 192 | }; 193 | -------------------------------------------------------------------------------- /resources/js/components/Alert.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 81 | 82 | 90 | -------------------------------------------------------------------------------- /resources/js/components/CodeEditor.vue: -------------------------------------------------------------------------------- 1 | 65 | 66 | 73 | -------------------------------------------------------------------------------- /resources/js/components/ContentSpace.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 28 | -------------------------------------------------------------------------------- /resources/js/components/DataTable.vue: -------------------------------------------------------------------------------- 1 | 64 | 65 | 141 | -------------------------------------------------------------------------------- /resources/js/components/Dropdown.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 30 | -------------------------------------------------------------------------------- /resources/js/components/FilesInput.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 39 | -------------------------------------------------------------------------------- /resources/js/components/HeaderFields.vue: -------------------------------------------------------------------------------- 1 | 46 | 47 | 64 | -------------------------------------------------------------------------------- /resources/js/components/HttpMethods.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 21 | 22 | 27 | -------------------------------------------------------------------------------- /resources/js/components/HttpResponseSize.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 24 | -------------------------------------------------------------------------------- /resources/js/components/HttpResponseTime.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 35 | -------------------------------------------------------------------------------- /resources/js/components/HttpStatus.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 58 | -------------------------------------------------------------------------------- /resources/js/components/Omnibox.vue: -------------------------------------------------------------------------------- 1 | 46 | 47 | 84 | -------------------------------------------------------------------------------- /resources/js/components/RequestTabs.vue: -------------------------------------------------------------------------------- 1 | 56 | 57 | 108 | -------------------------------------------------------------------------------- /resources/js/components/ResponseTabs.vue: -------------------------------------------------------------------------------- 1 | 38 | 39 | 69 | -------------------------------------------------------------------------------- /resources/js/components/SidebarMenu.vue: -------------------------------------------------------------------------------- 1 | 53 | 54 | 119 | 120 | 126 | -------------------------------------------------------------------------------- /resources/js/components/SiteHeader.vue: -------------------------------------------------------------------------------- 1 | 36 | -------------------------------------------------------------------------------- /resources/js/components/Spotlight.vue: -------------------------------------------------------------------------------- 1 | 136 | 137 | 236 | -------------------------------------------------------------------------------- /resources/js/components/request/AuthTab.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 45 | -------------------------------------------------------------------------------- /resources/js/components/request/BodyTab.vue: -------------------------------------------------------------------------------- 1 | 108 | 109 | 157 | -------------------------------------------------------------------------------- /resources/js/components/request/DocsTab.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 22 | -------------------------------------------------------------------------------- /resources/js/components/request/HeadersTab.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 16 | -------------------------------------------------------------------------------- /resources/js/components/request/ParamsTab.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 16 | -------------------------------------------------------------------------------- /resources/js/components/request/RouteTab.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 27 | -------------------------------------------------------------------------------- /resources/js/components/request/auth/Bearer.vue: -------------------------------------------------------------------------------- 1 | 125 | 126 | 175 | -------------------------------------------------------------------------------- /resources/js/components/request/auth/None.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 19 | -------------------------------------------------------------------------------- /resources/js/components/response/BodyTab.vue: -------------------------------------------------------------------------------- 1 | 38 | 39 |