yeashy / compliance
Pipeline Validation For Laravel Apps
Installs: 362
Dependents: 0
Suggesters: 0
Security: 0
Stars: 11
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/yeashy/compliance
Requires
- php: ^8.1
- laravel/framework: ^9.0 || ^10.0 || ^11.0 || ^12.0
Requires (Dev)
- orchestra/testbench: ^8.0 || ^9.0 || ^10.0
- phpunit/phpunit: ^10.0 || ^11.0 || ^12.0
This package is auto-updated.
Last update: 2025-09-18 07:54:16 UTC
README
Yeashy Compliance is an elegant pipeline-based validation system for Laravel, designed to extend FormRequest
validation with domain-driven, reusable, and expressive rule objects.
🚀 Features
- ✅ Seamless integration with Laravel
FormRequest
- 🧩 Pipeline-based rule processing
- 🎯 HTTP-method-specific rule handling (
GET
,POST
, etc.) - 🔁 Composable and testable rule classes
- 📦 Fully compatible with standard Laravel validation
📦 Installation
Install the package via Composer:
composer require yeashy/compliance
No additional service provider registration is required.
🧑💻 Getting Started
To use Compliance in your requests, simply extend the base ComplianceRequest
instead of Laravel’s FormRequest
.
Step 1: Create a Compliance Rule
A compliance rule is a class that extends Yeashy\Compliance\Rules\ComplianceRule
and implements the validate()
method.
use Yeashy\Compliance\Rules\ComplianceRule; class EmailIsNotBlocked extends ComplianceRule { protected string $key = 'email'; protected string $message = 'This email address is blocked.'; protected function validate(): void { if ($this->data->email === 'blocked@example.com') { $this->invalidateAndExit(); // Add error and stop the pipeline } } }
Step 2: Apply the Rule in a Request
Extend ComplianceRequest
and define the rules in the $compliances
property, or specify them per HTTP method ($postCompliances
, $getCompliances
, etc.).
use Yeashy\Compliance\Requests\ComplianceRequest; class RegisterRequest extends ComplianceRequest { protected array $postCompliances = [ \App\Compliance\Rules\EmailIsNotBlocked::class, ]; public function rules(): array { return [ 'email' => ['required', 'email'], 'password' => ['required'], ]; } }
That’s it! The request will now go through both Laravel’s standard validation and your custom compliance pipeline.
⚙️ How Compliance Rules Work
Each rule receives an object containing:
- All input data from the request
(Request::all())
- Route parameters
The validate()
method inside each rule is executed in sequence. You can:
- Use
invalidate($key, $message)
to add an error and continue to the next rule. - Use
invalidateAndExit()
to add an error and stop the pipeline immediately. - Use
skipNext()
to stop the pipeline without adding an error (optional shortcut).
HTTP Method Specific Rules
Compliance rules can be defined globally for all methods:
protected array $compliances = [...];`
Or scoped to specific HTTP verbs:
protected array $postCompliances = [...]; protected array $getCompliances = [...]; // Supported: get, post, put, patch, delete, head, options
Error Merging
Compliance errors are automatically merged with Laravel’s validation errors and returned in the standard format.
If a compliance rule sets a custom $statusCode
, it will override the default HTTP 422 status.
✅ Best Practices
- Rules should follow the Single Responsibility Principle: one rule — one concern.
- Use meaningful keys (
$key
) to ensure correct field mapping in error responses. - Localize messages using
__('...')
whenever possible. - Prefer
invalidateAndExit()
for critical rules (e.g., credential checks). - Use
skipNext()
if the current rule makes the remaining ones irrelevant.
📂 Example
Rule: Ensure the user is not blocked
use Illuminate\Support\Facades\Auth; use Yeashy\Compliance\Rules\ComplianceRule; class UserIsNotBlocked extends ComplianceRule { protected string $key = 'user'; protected string $message = 'Your account has been blocked.'; public int $statusCode = 403; protected function validate(): void { $user = Auth::user(); if (! $user || $user->is_blocked) { $this->invalidateAndExit(); } } }
Usage in Request:
use Yeashy\Compliance\Requests\ComplianceRequest; class DashboardRequest extends ComplianceRequest { protected array $compliances = [ \App\Compliance\Rules\UserIsNotBlocked::class, \App\Compliance\Rules\AccountIsVerified::class, ]; protected array $getCompliances = [ \App\Compliance\Rules\SubscriptionIsActive::class, \App\Compliance\Rules\UserHasAccessToResource::class, ]; public function rules(): array { return [ 'resource_id' => ['required', 'uuid'], ]; } }
In this example:
$compliances
defines global rules that apply to all HTTP methods.$getCompliances
defines additional rules applied only forGET
requests.- All rules are processed in order, and execution stops if a rule uses
invalidateAndExit()
.
🧪 Testing
You can test compliance rules in isolation:
public function test_email_is_not_blocked() { $rule = new EmailIsNotBlocked(); $data = (object) ['email' => 'blocked@example.com']; $rule->handle($data, fn($data) => $data); $this->assertNotEmpty($data->__errorMessages); }
📄 License
The MIT License (MIT). Please see License File for more information.
🤝 Contributing
Contributions, issues and feature requests are welcome! Feel free to submit a PR or open an issue.