Skip to content

Commit 1aa897c

Browse files
committed
Merge branch 'develop'
* develop: specify next release add documentation website CS update changelog allow to configure the failure message of Is::shape() allow to configure the failure message of PointInTime::ofFormat() allow to configure the failure message of primitive Is constraint allow to configure the failure message of Has::key() add Is::associativeArray() update actions versions add action to automatically create the releases
2 parents 55cd331 + df145a9 commit 1aa897c

28 files changed

+1167
-18
lines changed

.github/workflows/ci.yml

+5-5
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
extensions: mbstring, intl
2222
coverage: none
2323
- name: Composer
24-
uses: "ramsey/composer-install@v2"
24+
uses: "ramsey/composer-install@v3"
2525
with:
2626
dependency-versions: ${{ matrix.dependencies }}
2727
- name: BlackBox
@@ -44,14 +44,14 @@ jobs:
4444
extensions: mbstring, intl
4545
coverage: xdebug
4646
- name: Composer
47-
uses: "ramsey/composer-install@v2"
47+
uses: "ramsey/composer-install@v3"
4848
with:
4949
dependency-versions: ${{ matrix.dependencies }}
5050
- name: BlackBox
5151
run: php blackbox.php
5252
env:
5353
ENABLE_COVERAGE: 'true'
54-
- uses: codecov/codecov-action@v3
54+
- uses: codecov/codecov-action@v4
5555
with:
5656
token: ${{ secrets.CODECOV_TOKEN }}
5757
psalm:
@@ -70,7 +70,7 @@ jobs:
7070
php-version: ${{ matrix.php-version }}
7171
extensions: mbstring, intl
7272
- name: Composer
73-
uses: "ramsey/composer-install@v2"
73+
uses: "ramsey/composer-install@v3"
7474
with:
7575
dependency-versions: ${{ matrix.dependencies }}
7676
- name: Psalm
@@ -90,6 +90,6 @@ jobs:
9090
php-version: ${{ matrix.php-version }}
9191
extensions: mbstring, intl
9292
- name: Composer
93-
uses: "ramsey/composer-install@v2"
93+
uses: "ramsey/composer-install@v3"
9494
- name: CS
9595
run: vendor/bin/php-cs-fixer fix --diff --dry-run

.github/workflows/documentation.yml

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Documentation
2+
on:
3+
push:
4+
branches: [master]
5+
permissions:
6+
contents: write
7+
jobs:
8+
deploy:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v4
12+
- name: Configure Git Credentials
13+
run: |
14+
git config user.name github-actions[bot]
15+
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
16+
- uses: actions/setup-python@v5
17+
with:
18+
python-version: 3.x
19+
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
20+
- uses: actions/cache@v4
21+
with:
22+
key: mkdocs-material-${{ env.cache_id }}
23+
path: .cache
24+
restore-keys: |
25+
mkdocs-material-
26+
- run: pip install mkdocs-material
27+
- run: mkdocs gh-deploy --force

.github/workflows/release.yml

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Create release
2+
3+
on:
4+
push:
5+
tags:
6+
- '*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
release:
13+
name: Create release
14+
runs-on: ubuntu-22.04
15+
steps:
16+
- name: Create release
17+
env:
18+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
19+
tag: ${{ github.ref_name }}
20+
run: |
21+
gh release create "$tag" \
22+
--repo="$GITHUB_REPOSITORY" \
23+
--generate-notes

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/composer.lock
22
/vendor
3+
/.cache

CHANGELOG.md

+10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog
22

3+
## 1.5.0 - 2024-11-10
4+
5+
### Added
6+
7+
- `Is::associativeArray()`
8+
- `Has::key()->withFailure()` to change the failure message
9+
- `Is::string|int|float|array|bool|null()->withFailure()` to change the failure message
10+
- `PointInTime::ofFormat()->withFailure()` to change the failure message
11+
- `Is::shape()->withKeyFailure()` to change the failure message for when a key doesn't exist
12+
313
## 1.4.0 - 2024-03-24
414

515
### Added

Makefile

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# This command is intended to be run on your computer
2+
serve-doc:
3+
docker run --rm -it -p 8000:8000 -v ${PWD}:/docs squidfunk/mkdocs-material
4+
5+
build-doc:
6+
docker run --rm -it -v ${PWD}:/docs squidfunk/mkdocs-material build

docs/assets/favicon.png

2.26 KB
Loading
46.2 KB
Binary file not shown.

docs/assets/logo.svg

+24
Loading

docs/assets/stylesheets/extra.css

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
@font-face {
2+
font-family: "Monaspace Neon";
3+
font-weight: normal;
4+
font-style: normal;
5+
src: url("../fonts/MonaspaceNeon-Regular.woff");
6+
}
7+
8+
:root {
9+
--md-code-font: "Monaspace Neon";
10+
}
11+
12+
:root {
13+
--light-md-code-hl-number-color: #f76d47;
14+
--light-md-code-hl-function-color: #6384b9;
15+
--light-md-code-hl-operator-color: #39adb5;
16+
--light-md-code-hl-constant-color: #7c4dff;
17+
--light-md-code-hl-string-color: #9fc06f;
18+
--light-md-code-hl-punctuation-color: #39adb5;
19+
--light-md-code-hl-keyword-color: #7c4dff;
20+
--light-md-code-hl-variable-color: #80cbc4;
21+
--light-md-code-hl-comment-color: #ccd7da;
22+
--light-md-code-bg-color: #fafafa;
23+
--light-md-code-fg-color: #ffb62c;
24+
--light-md-code-hl-variable-color: #6384b9;
25+
--dark-md-code-hl-number-color: #f78c6c;
26+
--dark-md-code-hl-function-color: #82aaff;
27+
--dark-md-code-hl-operator-color: #89ddff;
28+
--dark-md-code-hl-constant-color: #c792ea;
29+
--dark-md-code-hl-string-color: #c3e88d;
30+
--dark-md-code-hl-punctuation-color: #89ddff;
31+
--dark-md-code-hl-keyword-color: #c792ea;
32+
--dark-md-code-hl-variable-color: #e8f9f9;
33+
--dark-md-code-hl-comment-color: #546e7a;
34+
--dark-md-code-bg-color: #263238;
35+
--dark-md-code-fg-color: #ffcb6b;
36+
--dark-md-code-hl-variable-color: #82aaff;
37+
}
38+
39+
@media (prefers-color-scheme: light) {
40+
.language-php > * {
41+
--md-code-hl-number-color: var(--light-md-code-hl-number-color);
42+
--md-code-hl-function-color: var(--light-md-code-hl-function-color);
43+
--md-code-hl-operator-color: var(--light-md-code-hl-operator-color);
44+
--md-code-hl-constant-color: var(--light-md-code-hl-constant-color);
45+
--md-code-hl-string-color: var(--light-md-code-hl-string-color);
46+
--md-code-hl-punctuation-color: var(--light-md-code-hl-punctuation-color);
47+
--md-code-hl-keyword-color: var(--light-md-code-hl-keyword-color);
48+
--md-code-hl-variable-color: var(--light-md-code-hl-variable-color);
49+
--md-code-hl-comment-color: var(--light-md-code-hl-comment-color);
50+
--md-code-bg-color: var(--light-md-code-bg-color);
51+
--md-code-fg-color: var(--light-md-code-fg-color);
52+
}
53+
54+
.language-php .na {
55+
--md-code-hl-variable-color: var(--light-md-code-hl-variable-color);
56+
}
57+
}
58+
59+
[data-md-color-media="(prefers-color-scheme: light)"] .language-php > * {
60+
--md-code-hl-number-color: var(--light-md-code-hl-number-color);
61+
--md-code-hl-function-color: var(--light-md-code-hl-function-color);
62+
--md-code-hl-operator-color: var(--light-md-code-hl-operator-color);
63+
--md-code-hl-constant-color: var(--light-md-code-hl-constant-color);
64+
--md-code-hl-string-color: var(--light-md-code-hl-string-color);
65+
--md-code-hl-punctuation-color: var(--light-md-code-hl-punctuation-color);
66+
--md-code-hl-keyword-color: var(--light-md-code-hl-keyword-color);
67+
--md-code-hl-variable-color: var(--light-md-code-hl-variable-color);
68+
--md-code-hl-comment-color: var(--light-md-code-hl-comment-color);
69+
--md-code-bg-color: var(--light-md-code-bg-color);
70+
--md-code-fg-color: var(--light-md-code-fg-color);
71+
}
72+
73+
[data-md-color-media="(prefers-color-scheme: light)"] .language-php .na {
74+
--md-code-hl-variable-color: var(--light-md-code-hl-variable-color);
75+
}
76+
77+
@media (prefers-color-scheme: dark) {
78+
.language-php > * {
79+
--md-code-hl-number-color: var(--dark-md-code-hl-number-color);
80+
--md-code-hl-function-color: var(--dark-md-code-hl-function-color);
81+
--md-code-hl-operator-color: var(--dark-md-code-hl-operator-color);
82+
--md-code-hl-constant-color: var(--dark-md-code-hl-constant-color);
83+
--md-code-hl-string-color: var(--dark-md-code-hl-string-color);
84+
--md-code-hl-punctuation-color: var(--dark-md-code-hl-punctuation-color);
85+
--md-code-hl-keyword-color: var(--dark-md-code-hl-keyword-color);
86+
--md-code-hl-variable-color: var(--dark-md-code-hl-variable-color);
87+
--md-code-hl-comment-color: var(--dark-md-code-hl-comment-color);
88+
--md-code-bg-color: var(--dark-md-code-bg-color);
89+
--md-code-fg-color: var(--dark-md-code-fg-color);
90+
}
91+
92+
.language-php .na {
93+
--md-code-hl-variable-color: var(--dark-md-code-hl-variable-color);
94+
}
95+
}
96+
97+
[data-md-color-media="(prefers-color-scheme: dark)"] .language-php > * {
98+
--md-code-hl-number-color: var(--dark-md-code-hl-number-color);
99+
--md-code-hl-function-color: var(--dark-md-code-hl-function-color);
100+
--md-code-hl-operator-color: var(--dark-md-code-hl-operator-color);
101+
--md-code-hl-constant-color: var(--dark-md-code-hl-constant-color);
102+
--md-code-hl-string-color: var(--dark-md-code-hl-string-color);
103+
--md-code-hl-punctuation-color: var(--dark-md-code-hl-punctuation-color);
104+
--md-code-hl-keyword-color: var(--dark-md-code-hl-keyword-color);
105+
--md-code-hl-variable-color: var(--dark-md-code-hl-variable-color);
106+
--md-code-hl-comment-color: var(--dark-md-code-hl-comment-color);
107+
--md-code-bg-color: var(--dark-md-code-bg-color);
108+
--md-code-fg-color: var(--dark-md-code-fg-color);
109+
}
110+
111+
[data-md-color-media="(prefers-color-scheme: dark)"] .language-php .na {
112+
--md-code-hl-variable-color: var(--dark-md-code-hl-variable-color);
113+
}

docs/constraints/array-shapes.md

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Array shape
2+
3+
Unlike an [associative array](associative-arrays.md), a shape is an array where the keys are known in advance.
4+
5+
```php
6+
use Innmind\Validation\Is;
7+
8+
$validate = Is::shape('id', Is::int())
9+
->with('username', Is::string());
10+
```
11+
12+
This contraint will accept any array that looks like:
13+
14+
```php
15+
[
16+
'id' => 42, #(1)
17+
'username' => 'any string',
18+
]
19+
```
20+
21+
1. or any `int`
22+
23+
If the input data contains more keys than the expected ones, the output will only contains the keys you specified. This is to prevent any unwanted data injection in your code.
24+
25+
## Optional keys
26+
27+
Here's an example of a login payload where the "Keep me logged in" is optional:
28+
29+
```php
30+
use Innmind\Validation\Is;
31+
32+
$validate = Is::shape('username', Is::string())
33+
->with('password', Is::string())
34+
->optional('keep-logged-in', Is::string());
35+
```
36+
37+
The optional key will only be present in the output value if it was set in the input.
38+
39+
??? tip
40+
If you want to build a shape with a single optional key you can do `#!php Is::shape('key', Is::string())->optional('key')`.
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Associative arrays
2+
3+
Here's the constraint to validate the HTTP response <https://packagist.org/packages/list.json?vendor=innmind&fields[]=repository&fields[]=abandoned>:
4+
5+
```php
6+
use Innmind\Validation\Is;
7+
8+
$validate = Is::associativeArray(
9+
Is::string(),
10+
Is::shape('repository', Is::string())
11+
->with('abandoned', Is::bool()->or(Is::string())),
12+
);
13+
```

docs/constraints/custom.md

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Custom
2+
3+
At some point you'll want to use your own constraints for a custom business logic. Instead of implementing the whole `Constraint` interface you can do:
4+
5+
```php
6+
use Innmind\Validation\{
7+
Of,
8+
Failure,
9+
};
10+
use Innmind\Immutable\Validation;
11+
12+
$validate = Of::callable(static function(mixed $input) {
13+
if (/* your validation here */) {
14+
return Validation::success($input);
15+
}
16+
17+
return Validation::fail(Failure::of('Your error message'));
18+
});
19+
```
20+
21+
And you can still compose it with any other constraint.
22+
23+
For example if you know the input has to be a `string` you can do:
24+
25+
```php hl_lines="7"
26+
use Innmind\Validation\{
27+
Of,
28+
Failure,
29+
};
30+
use Innmind\Immutable\Validation;
31+
32+
$validate = Is::string()->and(Of::callable(static function(string $input) {
33+
if (/* your validation here */) {
34+
return Validation::success($input);
35+
}
36+
37+
return Validation::fail(Failure::of('Your error message'));
38+
}));
39+
```
40+
41+
You don't need to write all the validations yourself in the `callable`.

docs/constraints/dates.md

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Dates
2+
3+
This will transform `string`s into `PointInTime`s from the [`innmind/time-continuum` package](https://github.com/Innmind/TimeContinuum/).
4+
5+
```php
6+
use Innmind\Validation\PointInTime;
7+
use Innmind\TimeContinuum\Earth\{
8+
Clock,
9+
Format\ISO8601,
10+
};
11+
12+
$validate = PointInTime::ofFormat(
13+
new Clock,
14+
new ISO8601,
15+
);
16+
```
17+
18+
??? tip
19+
Instead of creating the `Clock` yourself you should retrieve it from the [operating system abstraction](https://innmind.org/documentation/getting-started/operating-system/clock/).

0 commit comments

Comments
 (0)