|
1 | | -# Lemmon Validator - Project Overview |
| 1 | +# Lemmon Validator |
2 | 2 |
|
3 | | -A comprehensive, fluent validation library for PHP inspired by Valibot and Zod. This project provides type-safe validation with a symmetrical API for handling different data structures, advanced validation capabilities, and enterprise-grade documentation. |
| 3 | +PHP validation library inspired by Valibot and Zod. Type-safe, fluent API for primitives, arrays, and objects. |
4 | 4 |
|
5 | | -## Architecture |
6 | | - |
7 | | -- **Root Namespace** - Runtime classes live under `Lemmon\Validator`; tests use `Lemmon\Tests` |
8 | | - |
9 | | -### Core Factory Pattern |
10 | | -- **`Validator`** - Static factory creating type-specific validators (`isString()`, `isInt()`, `isFloat()`, `isArray()`, `isAssociative()`, `isObject()`, `isBool()`) |
11 | | -- **`FieldValidator`** - Abstract base class with unified validation interface and shared functionality |
12 | | -- **`ValidationException`** - Structured exception handling with aggregated error reporting |
13 | | - |
14 | | -### Type-Specific Validators |
15 | | -- **`StringValidator`** - Format validation (email, URL, UUID with version variants, IP with version variants, hostname, domain, time, base64 with variants, hex), length constraints, pattern matching |
16 | | -- **`IntValidator`** / **`FloatValidator`** - Numeric constraints via shared `NumericConstraintsTrait` (includes port validation for IntValidator) |
17 | | -- **`ArrayValidator`** - Indexed array validation with optional item validation |
18 | | -- **`AssociativeValidator`** / **`ObjectValidator`** - Schema-based validation for complex structures |
19 | | -- **`BoolValidator`** - Boolean validation with intelligent coercion |
20 | | - |
21 | | -### Shared Components |
22 | | -- **`NumericConstraintsTrait`** - Common numeric validations (`min()`, `max()`, `multipleOf()`, `positive()`, `negative()`, comparison helpers) |
23 | | -- **`PipelineType`** - Type-safe enum for pipeline operations (`VALIDATION`, `TRANSFORMATION`) with IDE support and refactoring safety |
24 | | -- **Variant Enums** - `IpVersion`, `Base64Variant`, and `UuidVariant` enums for type-safe variant selection in format validators |
25 | | - |
26 | | -## Advanced Features |
27 | | - |
28 | | -### Validation Capabilities |
29 | | -- **Static Logical Combinators** - `Validator::allOf()`, `Validator::anyOf()`, `Validator::not()` for complex rule composition and mixed-type validation |
30 | | -- **New `satisfies*` API** - Enhanced instance logical combinators (`satisfiesAny()`, `satisfiesAll()`, `satisfiesNone()`) with support for mixed validators/callables |
31 | | -- **Enum-Based Variant Flags** - Type-safe variant selection for IP addresses (`IpVersion`), Base64 encoding (`Base64Variant`), and UUID versions (`UuidVariant`) with consistent API pattern |
32 | | -- **Smart Null Handling** - Validations skip `null` unless `required()`. `transform()` runs on `null`, while `pipe()` and `nullifyEmpty()` skip `null` for type safety. |
33 | | -- **Form-Safe Coercion** - Empty strings convert to `null` (not dangerous `0`/`0.0`/`false`) for primitives, empty structures for objects/arrays |
34 | | -- **Array Filtering** - `filterEmpty()` method removes empty values while maintaining indexed array structure |
35 | | -- **Type-Aware Transformations** - Revolutionary `transform()` and `pipe()` system with intelligent type context switching |
36 | | -- **Unified Pipeline Architecture** - Single conceptual pipeline with ordered execution and fail-fast behavior per field |
37 | | -- **Custom Validation** - Enhanced `satisfies()` method accepting `FieldValidator` instances or callables with optional error messages (all internal validators migrated from deprecated `addValidation()`) |
38 | | -- **Context-Aware Validation** - Custom validators receive `(value, key, input)` parameters |
39 | | -- **Fail-Fast Per Field** - Each validator stops at the first failing rule, while schema validation aggregates errors across fields |
40 | | -- **Smart Type Coercion** - Configurable automatic type conversion with form-friendly defaults |
41 | | -- **Fluent API with guaranteed execution order** - Chainable method calls that execute in the exact order written |
42 | | -- **Extensibility Philosophy** - Focus on core validation principles; external libraries encouraged for advanced/specialized validators via `satisfies()` |
43 | | - |
44 | | -### Developer Experience |
45 | | -- **Dual Validation Methods** - `validate()` (exception-based) and `tryValidate()` (tuple-based) |
46 | | -- **Schema Validation** - Nested structure validation with hierarchical error reporting |
47 | | -- **Comprehensive Documentation** - Complete guides, API reference, and real-world examples |
48 | | - |
49 | | -## Documentation Structure |
50 | | - |
51 | | -### AI Agent Resources |
52 | | -- **`llms.txt`** - Complete technical specification with full API signatures, method parameters, and core concepts. This is the authoritative reference for AI agents working with the library. Contains complete method signatures, null handling behavior, transformation types, and quick examples. |
53 | | - |
54 | | -### Getting Started |
55 | | -- **Installation & Setup** - Requirements, installation, verification |
56 | | -- **Basic Usage** - Fundamental patterns, validation methods, common use cases |
57 | | -- **Core Concepts** - Architecture understanding, validation flow, performance considerations |
| 5 | +## Project Context |
58 | 6 |
|
59 | | -### Focused Guides |
60 | | -- **String Validation** - Complete format validation suite (email, URL, UUID, IP, hostname, domain, time, base64, hex) with enum-based variants and practical examples |
61 | | -- **Numeric Validation** - Integer and float validation with shared constraints, including port validation |
62 | | -- **Array Validation** - Indexed array validation with filtering and item validation |
63 | | -- **Object Validation** - Schema-based validation for complex structures |
64 | | -- **Custom Validation** - Business logic integration, context-aware validation, and external library integration patterns |
65 | | -- **Error Handling** - Exception vs tuple patterns, structured error reporting |
| 7 | +Core validation logic lives in `src/Lemmon/Validator/`. Tests in `tests/` follow `XValidatorTest.php` naming. Key project files: |
| 8 | +- `llms.txt` - Technical spec for external/consumer use; API signatures, null handling, transformation types |
| 9 | +- `ROADMAP.md` - Strategic planning and checkboxes |
| 10 | +- `TASKS.md` - Immediate task pool (keep short, no numbering) |
| 11 | +- `CHANGELOG` - Completed work |
| 12 | +- `IDEAS` - Exploration |
66 | 13 |
|
67 | | -### API Reference |
68 | | -- **Validator Factory** - Complete factory method documentation with usage patterns |
69 | | -- **Type-Specific APIs** - Detailed method references for each validator type |
70 | | - |
71 | | -### Practical Examples |
72 | | -- **Form Validation** - Contact forms, user registration, e-commerce products |
73 | | -- **Multi-Step Forms** - Complex validation workflows with session handling |
74 | | -- **Real-World Schemas** - Business logic validation patterns |
75 | | - |
76 | | -## Development Workflow |
77 | | - |
78 | | -### Code Quality |
79 | | -- **Testing** - Pest PHP with organized, focused test suite |
80 | | -- **Static Analysis** - PHPStan at maximum level for type safety |
81 | | -- **Code Style** - Mago for linting/formatting; scripts map `composer lint`/`composer fix` to Mago |
82 | | -- **Performance** - Optimized validation logic with eliminated code duplication |
83 | | - |
84 | | -### Development Guidelines |
85 | | -- **Documentation** - Add concise PHPDoc blocks where behavior is not immediately obvious, especially for helpers touching I/O streams |
86 | | -- **ASCII Punctuation** - Stick to ASCII punctuation in code and docs (prefer -- over em dashes) so diffs stay predictable |
87 | | -- **Emoji Usage** - Reserve emojis for rare emphasis; moderate use is fine for emphasis, but skip emoji-driven lists |
88 | | -- **Task Tracking** - Use GitHub-style checkboxes (`- [ ]` for pending, `- [x]` for completed) in ROADMAP.md for clear progress tracking |
89 | | -- **Task Pool** - Maintain immediate priorities in `TASKS.md`; keep it short, prune completed items, and avoid numbering to minimize churn |
90 | | -- **Commit Standards** - Follow Conventional Commits spec (e.g., `fix:`, `refactor:`, `docs:`) |
91 | | -- **Commit Scope** - Each commit should address a single concern; tests and implementation can ship together, but unrelated formatting belongs elsewhere |
92 | | -- **Commit Format** - Use concise Conventional Commit summaries: `<type>(<scope>): <short action>`. Avoid verbose release blurbs in commit messages; keep release notes in CHANGELOG/release tagging. |
93 | | -- **Git Tags** - Prefer annotated tags for releases (author, date, message/signing) over lightweight tags |
94 | | -- **Tag Format** - Annotated tags should use `vX.Y.Z - <concise headline>`; keep detailed notes in CHANGELOG/releases |
95 | | - |
96 | | -### Development Tools |
97 | | -- **Debugging** - `symfony/var-dumper` integration |
98 | | -- **Error Handling** - `symfony/error-handler` for development |
99 | | -- **Composer Normalization** - `ergebnis/composer-normalize` for consistent composer.json formatting |
100 | | -- **Composer Scripts** - `test`, `lint`, `fix`, `analyse` commands |
101 | | - |
102 | | -### Test Organization |
103 | | -``` |
104 | | -tests/ |
105 | | -├── AssociativeValidatorTest.php # Schema validation |
106 | | -├── ObjectValidatorTest.php # stdClass validation |
107 | | -├── ArrayValidatorTest.php # Indexed arrays |
108 | | -├── StringValidatorTest.php # String formats |
109 | | -├── IntValidatorTest.php # Integer constraints |
110 | | -├── FloatValidatorTest.php # Float constraints |
111 | | -├── BoolValidatorTest.php # Boolean validation |
112 | | -├── FieldValidatorTest.php # Base functionality |
113 | | -├── NumericConstraintsTraitTest.php # Shared numeric logic |
114 | | -└── ValidatorStaticCombinatorsTest.php # Static logical combinators |
115 | | -``` |
116 | | - |
117 | | -## Architecture Overview |
118 | | - |
119 | | -### Core Components |
120 | | -- **8 validator types** covering all PHP data types |
121 | | -- **Unified pipeline architecture** with smart null handling and execution order guarantees |
122 | | -- **Type-safe internal structure** using modern PHP 8.1+ enums |
123 | | -- **Comprehensive test coverage** across all validator types |
124 | | -- **Enterprise-grade documentation** with practical examples and complete API reference |
125 | | - |
126 | | -## Vision & Roadmap |
127 | | - |
128 | | -This library aims to be the definitive validation solution for PHP applications, providing: |
129 | | -- **Developer Productivity** -- Intuitive API with excellent documentation |
130 | | -- **Type Safety** -- Leveraging PHP's type system for robust validation |
131 | | -- **Performance** -- Optimized validation logic for high-throughput applications |
132 | | -- **Extensibility** -- Custom validation support for business-specific requirements |
133 | | -- **Enterprise Ready** -- Comprehensive error handling and structured feedback |
| 14 | +## Architecture |
134 | 15 |
|
135 | | -The project maintains a clear separation between completed features (CHANGELOG), strategic planning (ROADMAP), and innovative ideas (IDEAS), ensuring focused development and clear project management. |
| 16 | +- **Namespace:** `Lemmon\Validator` (runtime), `Lemmon\Tests` (tests) |
| 17 | +- **Core:** `Validator` static factory; `FieldValidator` base; `ValidationException` for errors |
| 18 | +- **Validators:** `isString`, `isInt`, `isFloat`, `isBool`, `isArray`, `isAssociative`, `isObject` |
| 19 | +- **Shared:** `NumericConstraintsTrait` (min, max, multipleOf, etc.); `PipelineType` enum; variant enums `IpVersion`, `Base64Variant`, `UuidVariant` for format methods |
| 20 | +- **String formats:** email, URL, UUID, IP, hostname, domain, time, base64, hex, regex, datetime, date |
| 21 | +- **Schema validation:** AssociativeValidator/ObjectValidator with nested error aggregation |
| 22 | +- **Logical combinators:** `Validator::allOf`, `anyOf`, `not`; instance `satisfiesAny`, `satisfiesAll`, `satisfiesNone` |
| 23 | +- **Behavior:** Optional by default (null allowed unless `required()`); form-safe coercion (empty string → null, not 0/false); pipeline order guaranteed; fail-fast per field; `satisfies()` accepts validators or callables with `(value, key, input)`; extend via `satisfies()`, not custom validators |
| 24 | + |
| 25 | +## Build, Test, and Development Commands |
| 26 | + |
| 27 | +- `composer test` - Run Pest test suite |
| 28 | +- `composer lint` / `composer format` - Mago linting and formatting (dev dependency) |
| 29 | +- `composer analyse` - PHPStan at max level |
| 30 | +- `composer platform-check` - Verify PHP 8.3 and extension requirements |
| 31 | + |
| 32 | +`config.platform.php` is set to `8.3.0` so dependency resolution targets PHP 8.3; `composer update`/`install` will not add packages that require PHP above 8.3. |
| 33 | + |
| 34 | +Dev tooling: symfony/var-dumper, symfony/error-handler, ergebnis/composer-normalize. |
| 35 | + |
| 36 | +## Coding Style & Formatting |
| 37 | + |
| 38 | +PSR-12 for PHP. Mago for lint/format (`composer lint`, `composer format`). Prettier (`.prettierrc`) for YAML, JSON, Markdown. Add PHPDoc where behavior is non-obvious. Stick to ASCII punctuation in code and docs (e.g. `--` not em dash) so diffs stay predictable. Emojis sparingly. |
| 39 | + |
| 40 | +## Commit Message Guidelines |
| 41 | + |
| 42 | +- Commit messages must follow Conventional Commits |
| 43 | +- Subject format: `<type>(<scope>): <summary>`; use `<type>: <summary>` when scope is omitted |
| 44 | +- Allowed `type` values: `feat`, `fix`, `refactor`, `perf`, `docs`, `test`, `build`, `ci`, `chore`, `revert` |
| 45 | +- `scope` is optional but recommended when it narrows the area (e.g. `StringValidator`, `FieldValidator`, `AssociativeValidator`) |
| 46 | +- Write summary lines in imperative mood, keep them concise (around 72 characters when practical), and omit trailing periods |
| 47 | +- Keep each commit focused on one concern; include related tests or validation updates in the same commit when applicable |
| 48 | +- Prefer bullet lists in commit bodies for concrete changes, with one logical change per bullet |
| 49 | +- Commit body bullets should start with a capitalized imperative verb and omit trailing periods |
| 50 | +- Avoid unnecessary noise in commit bodies; include only explicit, intentional, non-obvious updates |
| 51 | +- Do not call out secondary artifact changes (for example lockfile refreshes) unless they carry non-obvious impact |
| 52 | +- Add a short prose paragraph only when extra context is needed (rationale, tradeoffs, migration notes, risks, or non-obvious impact) |
| 53 | +- Separate subject, body, and footers with blank lines |
| 54 | +- Use optional footers in `Key: Value` format; preferred keys: `Refs`, `Closes`, `Fixes`, `PR`, `BREAKING CHANGE` |
| 55 | +- Breaking changes must include a `BREAKING CHANGE:` footer |
| 56 | +- Release notes belong in CHANGELOG, not commit body. Tag format: annotated `vX.Y.Z - <headline>`; details in CHANGELOG/releases |
| 57 | +- Quick templates: `fix(scope): <imperative summary>` and `feat(scope): <imperative summary>` |
0 commit comments