Skip to content

Commit 58590e8

Browse files
committed
chore: platform config, CI, tooling updates, and codebase tidy
- Add config.platform.php 8.3.0, composer platform-check - Add GitHub Actions CI (lint, analyse, test on PHP 8.3) - Add .prettierrc for YAML/JSON/MD; .vscode/settings.json - Rename composer fix to composer format; Mago as dev dependency - Update mago.toml; apply formatting and linter rules (readable-literal, no-isset) - Update AGENTS, CONTRIBUTING, ROADMAP, IDEAS, CHANGELOG
1 parent 2145cdd commit 58590e8

23 files changed

Lines changed: 591 additions & 462 deletions

.github/workflows/ci.yml

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,55 @@
11
name: CI
22

33
on:
4-
push:
5-
branches: [ main ]
6-
pull_request:
7-
branches: [ main ]
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
workflow_dispatch:
89

910
jobs:
10-
build:
11-
runs-on: ubuntu-latest
11+
ci:
12+
name: Lint, Analyse, Test
13+
runs-on: ubuntu-latest
14+
timeout-minutes: 15
1215

13-
steps:
14-
- uses: actions/checkout@v3
16+
steps:
17+
- name: Checkout
18+
uses: actions/checkout@v4
1519

16-
- name: Validate composer.json and composer.lock
17-
run: composer validate --strict
20+
- name: Setup PHP
21+
uses: shivammathur/setup-php@v2
22+
with:
23+
php-version: "8.3"
24+
tools: composer:v2
25+
coverage: none
1826

19-
- name: Cache Composer packages
20-
id: composer-cache
21-
uses: actions/cache@v3
22-
with:
23-
path: vendor
24-
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
25-
restore-keys: |
26-
${{ runner.os }}-php-
27+
- name: Get Composer cache directory
28+
id: composer-cache
29+
run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT"
2730

28-
- name: Install dependencies
29-
run: composer install --prefer-dist --no-progress
31+
- name: Cache Composer packages
32+
uses: actions/cache@v4
33+
with:
34+
path: ${{ steps.composer-cache.outputs.dir }}
35+
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
36+
restore-keys: |
37+
${{ runner.os }}-composer-
3038
31-
- name: Run test suite
32-
run: vendor/bin/pest
39+
- name: Validate Composer
40+
run: composer validate --strict --no-check-publish
41+
42+
- name: Install dependencies
43+
run: composer install --no-interaction --no-progress --prefer-dist
44+
45+
- name: Platform check
46+
run: composer platform-check
47+
48+
- name: Lint
49+
run: composer lint
50+
51+
- name: Static analysis
52+
run: composer analyse
53+
54+
- name: Tests
55+
run: composer test

.prettierrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

.vscode/settings.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"editor.formatOnSave": true,
3+
"files.exclude": {
4+
"composer.lock": true,
5+
"vendor": true
6+
},
7+
"files.trimFinalNewlines": true
8+
}

AGENTS.md

Lines changed: 52 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -1,135 +1,57 @@
1-
# Lemmon Validator - Project Overview
1+
# Lemmon Validator
22

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.
44

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
586

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
6613

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
13415

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>`

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file.
44

55
## [Unreleased]
66

7+
### Added
8+
- GitHub Actions CI: lint, platform-check, static analysis, tests on PHP 8.3
9+
10+
### Changed
11+
- Applied Mago formatting and new linter rules across the codebase (readable-literal, no-isset); updated mago.toml (print-width 120, preserve-breaking-* options)
12+
- Renamed `composer fix` script to `composer format` for Mago formatting
13+
- Mago now a dev dependency (carthage-software/mago) instead of global installation
14+
- Added `config.platform.php: "8.3.0"` so dependency resolution targets PHP 8.3; `composer update`/`install` will not add packages requiring PHP above 8.3
15+
- Added `composer platform-check` script to verify platform requirements
16+
717
## [0.12.0] - 2026-01-24
818

919
### Changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@ To get started, you will need to have PHP 8.3+ and Composer installed.
2222
## Pull Requests
2323

2424
- Please ensure that the tests are passing before submitting a pull request.
25-
- Please follow the existing code style.
25+
- Please follow the existing code style: Mago for PHP (`composer lint` / `composer format`); Prettier for YAML, JSON, Markdown (`.prettierrc`).
2626
- Please add a clear description of the changes you have made.

0 commit comments

Comments
 (0)