Skip to content

Commit e1bb888

Browse files
committed
docs: add AI agent resources and technical specification
- Introduced `llms.txt` containing comprehensive technical specifications, API signatures, and core concepts for AI agents. - Updated AGENTS.md and README.md to reference the new `llms.txt` file for improved guidance on using the library with AI agents.
1 parent aaadd3d commit e1bb888

3 files changed

Lines changed: 176 additions & 0 deletions

File tree

AGENTS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ A comprehensive, fluent validation library for PHP inspired by Valibot and Zod.
4848

4949
## Documentation Structure
5050

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+
5154
### Getting Started
5255
- **Installation & Setup** - Requirements, installation, verification
5356
- **Basic Usage** - Fundamental patterns, validation methods, common use cases

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ try {
108108
### Examples
109109
- [Form Validation](docs/examples/form-validation.md)
110110

111+
### For AI Agents
112+
- **`llms.txt`** - Complete technical specification with full API signatures, method parameters, and core concepts. Download this file and provide it to your AI agent for accurate code generation and assistance with the library.
113+
111114
## Contributing
112115

113116
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.

llms.txt

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
# Lemmon/Validator Technical Spec
2+
3+
## Core Concepts
4+
- **Form-Safe Coercion:** `coerce()` converts types but treats empty strings `''` as `null` for `Int`, `Float`, and `Bool` to prevent dangerous defaults (0/false).
5+
- **Optional by Default:** All fields accept `null` unless `required()` is called.
6+
- **Null Handling:**
7+
- **Validations** (`satisfies`, `min`, `email`): Skip `null` values.
8+
- **Transformations**:
9+
- `pipe(callable)`: Skips `null` values (type-preserving, expects specific type).
10+
- `transform(callable)`: Executes on `null` (can handle null and change types).
11+
- **Pipeline Order:** Operations execute in the exact order defined (e.g., `pipe('trim')->nullifyEmpty()->required()`).
12+
- **Transformation Types:**
13+
- `pipe(callable)`: Intended for sanitization. Preserves type context and applies type-coercion to result.
14+
- `transform(callable)`: Intended for type conversion. Updates type context; no coercion.
15+
16+
## Core Patterns
17+
- **Namespace:** `Lemmon\Validator`
18+
- **Entry Point:** `Validator` static factory (e.g., `Validator::isString()`).
19+
- **Fluency:** Validators are mutable during configuration but used sequentially.
20+
- **Execution:**
21+
- `validate(mixed $value, string $key = '', array $input = [])` throws `ValidationException`.
22+
- `tryValidate(mixed $value, string $key = '', mixed $input = null)` returns tuple `[bool $valid, mixed $data, ?array $errors]`.
23+
- **Error Structure:** `ValidationException` contains nested array of error messages. Use `getFlattenedErrors()` for API format `[{path: string, message: string}]`.
24+
- **Null Handling:** Validators skip `null` values unless `required()` is called.
25+
- **Pipeline:** Supports both validation (`satisfies`) and transformation (`transform`, `pipe`).
26+
- **Coercion:** `coerce()` enables smart type conversion (e.g., "true" -> `true`). Non-coercible values pass through unchanged.
27+
- **Form Safety:** Empty strings `''` are treated as `null` for primitives if coerced.
28+
29+
## API Reference
30+
31+
### Factory (`Lemmon\Validator\Validator`)
32+
```php
33+
static isString(): StringValidator
34+
static isInt(): IntValidator
35+
static isFloat(): FloatValidator
36+
static isBool(): BoolValidator
37+
static isArray(): ArrayValidator
38+
static isAssociative(array<string, FieldValidator> $schema = []): AssociativeValidator
39+
static isObject(array<string, FieldValidator> $schema = []): ObjectValidator
40+
static anyOf(array<FieldValidator> $validators, ?string $message = null): FieldValidator
41+
static allOf(array<FieldValidator> $validators, ?string $message = null): FieldValidator
42+
static not(FieldValidator $validator, ?string $message = null): FieldValidator
43+
```
44+
45+
### Base API (`FieldValidator`)
46+
*Available on all validators*
47+
```php
48+
required(?string $message = null): static
49+
default(mixed $value): static
50+
coerce(): static
51+
nullifyEmpty(): static (transforms '' or [] to null)
52+
clone(): static (deep copy with bound closures)
53+
54+
// Custom Validation
55+
satisfies(callable|FieldValidator $rule, ?string $message = null): static
56+
satisfiesAny(array<callable|FieldValidator> $rules, ?string $message = null): static
57+
satisfiesAll(array<callable|FieldValidator> $rules, ?string $message = null): static
58+
satisfiesNone(array<callable|FieldValidator> $rules, ?string $message = null): static
59+
60+
// Transformation
61+
transform(callable $fn): static (can change type)
62+
pipe(callable ...$fns): static (preserves type, skips null)
63+
```
64+
65+
### StringValidator
66+
```php
67+
email(?string $message = null): static
68+
url(?string $message = null): static
69+
uuid(UuidVariant $variant = UuidVariant::Any, ?string $message = null): static
70+
ip(IpVersion $version = IpVersion::Any, ?string $message = null): static
71+
hostname(?string $message = null): static
72+
domain(?string $message = null): static // Requires dot
73+
time(?string $message = null): static // HH:MM or HH:MM:SS
74+
base64(Base64Variant $variant = Base64Variant::Standard, ?string $message = null): static
75+
hex(?string $message = null): static
76+
regex(string $pattern, ?string $message = null): static // Alias for pattern()
77+
pattern(string $pattern, ?string $message = null): static
78+
datetime(string $format = 'Y-m-d\TH:i:s', ?string $message = null): static
79+
date(string $format = 'Y-m-d', ?string $message = null): static
80+
minLength(int $min, ?string $message = null): static
81+
maxLength(int $max, ?string $message = null): static
82+
length(int $exact, ?string $message = null): static
83+
oneOf(array $values, ?string $message = null): static
84+
```
85+
86+
### IntValidator / FloatValidator
87+
*Both support NumericConstraintsTrait*
88+
```php
89+
min(int|float $min, ?string $message = null): static
90+
max(int|float $max, ?string $message = null): static
91+
gt(int|float $threshold, ?string $message = null): static
92+
gte(int|float $threshold, ?string $message = null): static
93+
lt(int|float $threshold, ?string $message = null): static
94+
lte(int|float $threshold, ?string $message = null): static
95+
multipleOf(int|float $divisor, ?string $message = null): static
96+
positive(?string $message = null): static
97+
negative(?string $message = null): static
98+
nonPositive(?string $message = null): static
99+
nonNegative(?string $message = null): static
100+
clampToRange(int|float $min, int|float $max): static // Transformation, not validation
101+
oneOf(array $values, ?string $message = null): static
102+
```
103+
*IntValidator Only:*
104+
```php
105+
port(?string $message = null): static // 1-65535
106+
```
107+
108+
### ArrayValidator (`Validator::isArray()`)
109+
*Indexed arrays / Lists*
110+
```php
111+
items(FieldValidator $validator): static
112+
filterEmpty(): static (removes null/'', reindexes)
113+
minItems(int $min, ?string $message = null): static
114+
maxItems(int $max, ?string $message = null): static
115+
contains(mixed|FieldValidator $valueOrValidator, ?string $message = null): static
116+
```
117+
118+
### AssociativeValidator / ObjectValidator
119+
*Schema validation*
120+
```php
121+
// Constructor accepts array<string, FieldValidator>
122+
coerceAll(): static // Recursively enables coercion on schema fields
123+
```
124+
125+
### BoolValidator
126+
```php
127+
oneOf(array $values, ?string $message = null): static
128+
// Coercion handles: 'true','on','1' -> true; 'false','off','0' -> false
129+
```
130+
131+
## Enums
132+
133+
### IpVersion
134+
`Any`, `IPv4`, `IPv6`
135+
136+
### UuidVariant
137+
`Any`, `V1`, `V2`, `V3`, `V4`, `V5`, `V7`
138+
139+
### Base64Variant
140+
`Standard`, `UrlSafe`, `Any`
141+
142+
### PipelineType
143+
`VALIDATION`, `TRANSFORMATION`
144+
145+
## Quick Examples
146+
```php
147+
// Pipeline order: pipe (same type) -> validate -> transform (type change)
148+
Validator::isString()
149+
->pipe('trim') // String operations (preserves type)
150+
->nullifyEmpty()
151+
->required()
152+
->date('Y-m-d')
153+
->transform(fn($s) => DateTime::createFromFormat('Y-m-d', $s)); // String → DateTime
154+
155+
// Form-safe coercion: '' -> null (not 0/false)
156+
Validator::isInt()->coerce()->validate(''); // null (if not required)
157+
158+
// Schema with defaults
159+
Validator::isAssociative([
160+
'name' => Validator::isString()->required(),
161+
'age' => Validator::isInt()->default(0)
162+
]);
163+
164+
// Error handling
165+
try {
166+
$data = $validator->validate($input);
167+
} catch (ValidationException $e) {
168+
$errors = $e->getFlattenedErrors(); // [{path: 'field', message: '...'}]
169+
}
170+
```

0 commit comments

Comments
 (0)