Skip to content

Commit eb7fc82

Browse files
committed
Big 💥
0 parents  commit eb7fc82

23 files changed

+1048
-0
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/vendor/
2+
/composer.lock
3+
/.phpcs-cache
4+
/phpcs.xml
5+
/phpstan.neon
6+
/phpunit.xml

.scrutinizer.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
build:
2+
nodes:
3+
analysis:
4+
environment:
5+
php:
6+
version: 7.2
7+
cache:
8+
disabled: false
9+
directories:
10+
- ~/.composer/cache
11+
project_setup:
12+
override: true
13+
tests:
14+
override:
15+
- php-scrutinizer-run
16+
- phpcs-run
17+
dependencies:
18+
override:
19+
- composer install --no-interaction --prefer-dist
20+
21+
checks:
22+
php:
23+
code_rating: true
24+
25+
tools:
26+
external_code_coverage: true
27+
28+
build_failure_conditions:
29+
- 'elements.rating(<= C).new.exists' # No new classes/methods with a rating of C or worse allowed
30+
- 'issues.severity(>= MAJOR).new.exists' # New issues of major or higher severity
31+
- 'project.metric_change("scrutinizer.test_coverage", < 0)' # Code Coverage decreased from previous inspection
32+
- 'patches.label("Unused Use Statements").new.exists' # No new unused imports patches allowed

.travis.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
dist: trusty
2+
language: php
3+
sudo: false
4+
5+
cache:
6+
directories:
7+
- $HOME/.composer/cache
8+
9+
php:
10+
- 7.2
11+
- nightly
12+
13+
before_install:
14+
- composer self-update
15+
- mv ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini{,.disabled} || echo "xdebug not available"
16+
17+
install:
18+
- travis_retry composer update --prefer-dist
19+
20+
script: ./vendor/bin/phpunit
21+
22+
jobs:
23+
include:
24+
- stage: Test
25+
env: COVERAGE
26+
php: 7.2
27+
before_script:
28+
- mv ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini{.disabled,}
29+
- if [[ ! $(php -m | grep -si xdebug) ]]; then echo "xdebug required for coverage"; exit 1; fi
30+
script:
31+
- ./vendor/bin/phpunit --coverage-clover ./build/logs/clover.xml
32+
after_script:
33+
- wget https://github.com/scrutinizer-ci/ocular/releases/download/1.5.2/ocular.phar
34+
- php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml
35+
36+
- stage: Code Quality
37+
env: CODING_STANDARD
38+
php: 7.2
39+
script:
40+
- ./vendor/bin/phpcs
41+
42+
- stage: Code Quality
43+
env: STATIC_ANALYSIS
44+
php: 7.2
45+
script:
46+
- ./vendor/bin/phpstan analyse
47+

LICENCE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2018 Šimon Podlipský <[email protected]>
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of
4+
this software and associated documentation files (the "Software"), to deal in
5+
the Software without restriction, including without limitation the rights to
6+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7+
of the Software, and to permit persons to whom the Software is furnished to do
8+
so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.

README.md

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
# PHP GraphQL Utils for graphql-php
2+
3+
[![Build Status](https://travis-ci.org/simPod/GraphQL-Utils.svg)](https://travis-ci.org/simPod/GraphQL-Utils)
4+
[![Downloads](https://poser.pugx.org/simpod/graphql-utils/d/total.svg)](https://packagist.org/packages/simpod/graphql-utils)
5+
[![Packagist](https://poser.pugx.org/simpod/graphql-utils/v/stable.svg)](https://packagist.org/packages/simpod/graphql-utils)
6+
[![Licence](https://poser.pugx.org/simpod/graphql-utils/license.svg)](https://packagist.org/packages/simpod/graphql-utils)
7+
[![Quality Score](https://scrutinizer-ci.com/g/simPod/GraphQL-Utils/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/simPod/GraphQL-Utils)
8+
[![Code Coverage](https://scrutinizer-ci.com/g/simPod/GraphQL-Utils/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/simPod/GraphQL-Utils)
9+
[![GitHub Issues](https://img.shields.io/github/issues/simPod/GraphQL-Utils.svg?style=flat-square)](https://github.com/simPod/GraphQL-Utils/issues)
10+
11+
12+
## Contents
13+
- [Installation](#installation)
14+
- [Features](#features)
15+
- [Schema Builders](#schema-builders)
16+
- [Types](#types)
17+
- [Error Handling](#error-handling)
18+
19+
## Installation
20+
21+
Add as [Composer](https://getcomposer.org/) dependency:
22+
23+
```sh
24+
composer require simpod/graphql-utils
25+
```
26+
27+
## Features
28+
29+
### Schema Builders
30+
31+
Instead of defining your schema as an array, use can use more objective-oriented approach.
32+
This library provides set of strictly typed builders that help you build your schema.
33+
34+
#### ObjectBuilder and FieldBuilder
35+
36+
✔️ Standard way with `webonyx/graphql-php`
37+
38+
```php
39+
$userType = new ObjectType([
40+
'name' => 'User',
41+
'description' => 'Our blog visitor',
42+
'fields' => [
43+
'firstName' => [
44+
'type' => Type::string(),
45+
'description' => 'User first name'
46+
],
47+
'email' => Type::string()
48+
]
49+
]);
50+
```
51+
52+
✨ The same can be produced in objective way
53+
54+
```php
55+
use SimPod\GraphQLUtils\Builder\ObjectBuilder;
56+
57+
...
58+
59+
$userType = ObjectBuilder::create('User')
60+
->setDescription('Our blog visitor')
61+
->setFields([
62+
FieldBuilder::create('firstName', Type::string())
63+
->setDescription('User first name')
64+
->build(),
65+
FieldBuilder::create('email', Type::string())
66+
->build(),
67+
])
68+
->build();
69+
70+
```
71+
72+
#### EnumBuilder
73+
74+
✔️ Standard way with `webonyx/graphql-php`
75+
76+
```php
77+
use SimPod\GraphQLUtils\Builder\EnumBuilder;
78+
79+
...
80+
81+
$episodeEnum = new EnumType([
82+
'name' => 'Episode',
83+
'description' => 'One of the films in the Star Wars Trilogy',
84+
'values' => [
85+
'NEWHOPE' => [
86+
'value' => 4,
87+
'description' => 'Released in 1977.'
88+
],
89+
'EMPIRE' => [
90+
'value' => 5,
91+
'description' => 'Released in 1980.'
92+
],
93+
'JEDI' => [
94+
'value' => 6,
95+
'description' => 'Released in 1983.'
96+
],
97+
]
98+
]);
99+
```
100+
101+
✨ The same can be produced in objective way
102+
103+
```php
104+
$episodeEnum = EnumBuilder::create('Episode')
105+
->setDescription('One of the films in the Star Wars Trilogy')
106+
->addValue(4, 'NEWHOPE', 'Released in 1977.')
107+
->addValue(5, 'EMPIRE', 'Released in 1980.')
108+
->addValue(6, 'JEDI', 'Released in 1983.')
109+
->build();
110+
```
111+
112+
### Types
113+
114+
#### 🕰️ DateTime
115+
116+
scalar type that produces `scalar DateTime` in your schema.
117+
118+
[`SimPod\GraphQLUtils\Type\DateTimeType`](https://github.com/simPod/GraphQL-Utils/blob/master/src/Type/DateTimeType.php)
119+
120+
### Error Handling
121+
122+
Extending your exception with `SimPod\GraphQLUtils\Error\Error` forces you to implement `getType()` method.
123+
124+
Example Error class
125+
126+
```php
127+
use SimPod\GraphQLUtils\Error\Error;
128+
use function sprintf;
129+
130+
final class InvalidCustomerIdProvided extends Error
131+
{
132+
public const TYPE = 'INVALID_CUSTOMER_ID_PROVIDED';
133+
134+
public static function noneGiven() : self
135+
{
136+
return new self('No CustomerId provided');
137+
}
138+
139+
public function getType() : string
140+
{
141+
return self::TYPE;
142+
}
143+
144+
public function isClientSafe() : bool
145+
{
146+
return true;
147+
}
148+
}
149+
```
150+
151+
Create your formatter
152+
153+
```php
154+
use SimPod\GraphQLUtils\Error\FormattedError;
155+
156+
$formatError = function formatError(Error $error) : array
157+
{
158+
if (!$error->isClientSafe()) {
159+
// eg. log error
160+
}
161+
162+
return FormattedError::createFromException($error);
163+
};
164+
165+
$errorFormatterCallback = static function (Error $error) use ($formatError) : array {
166+
return $formatError($error);
167+
};
168+
169+
$config = GraphQL::executeQuery(/* $args */)
170+
...
171+
->setErrorFormatter($errorFormatterCallback)
172+
->setErrorsHandler(
173+
static function (array $errors, callable $formatter) : array {
174+
return array_map($formatter, $errors);
175+
}
176+
)
177+
```
178+
179+
Error types will then be provided in your response so client can easier identify the error type
180+
181+
```json
182+
{
183+
"errors": [
184+
{
185+
"type": "INVALID_CUSTOMER_ID_PROVIDED",
186+
"message": "No CustomerId provided",
187+
"category": "graphql",
188+
...
189+
```

composer.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "simpod/graphql-utils",
3+
"description": "GraphQL Utils for graphql-php",
4+
"type": "library",
5+
"license": "MIT",
6+
"authors": [
7+
{
8+
"name": "Simon Podlipsky",
9+
"email": "[email protected]"
10+
}
11+
],
12+
"config": {
13+
"sort-packages": true
14+
},
15+
"require": {
16+
"php": "^7.2",
17+
"webonyx/graphql-php": "^0.12"
18+
},
19+
"require-dev": {
20+
"doctrine/coding-standard": "^5.0",
21+
"phpstan/phpstan": "^0.10.3",
22+
"phpstan/phpstan-phpunit": "^0.10.0",
23+
"phpstan/phpstan-strict-rules": "^0.10.1",
24+
"phpunit/phpunit": "^7.0"
25+
},
26+
"autoload": {
27+
"psr-4": {
28+
"SimPod\\GraphQLUtils\\": "src/"
29+
}
30+
},
31+
"autoload-dev": {
32+
"psr-4": {
33+
"SimPod\\GraphQLUtils\\Tests\\": "tests/"
34+
}
35+
}
36+
}

phpcs.xml.dist

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0"?>
2+
<ruleset>
3+
<arg name="basepath" value="."/>
4+
<arg name="extensions" value="php"/>
5+
<arg name="parallel" value="80"/>
6+
<arg name="cache" value=".phpcs-cache"/>
7+
<arg name="colors"/>
8+
9+
<!-- Ignore warnings, show progress of the run and show sniff names -->
10+
<arg value="nps"/>
11+
12+
<file>src</file>
13+
14+
<rule ref="Doctrine"/>
15+
</ruleset>

phpstan.neon.dist

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
parameters:
2+
level: max
3+
paths:
4+
- %currentWorkingDirectory%/src
5+
- %currentWorkingDirectory%/tests
6+
tmpDir: %currentWorkingDirectory%/var/phpstan
7+
ignoreErrors:
8+
- "~Method SimPod\\\\GraphQLUtils\\\\Error\\\\FormattedError::createFromException\\(\\) has parameter \\$\\w+ with no typehint specified~"
9+
10+
includes:
11+
- vendor/phpstan/phpstan-phpunit/extension.neon
12+
- vendor/phpstan/phpstan-phpunit/rules.neon
13+
- vendor/phpstan/phpstan-strict-rules/rules.neon

phpunit.xml.dist

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
4+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
6+
beStrictAboutChangesToGlobalState="true"
7+
beStrictAboutOutputDuringTests="true"
8+
beStrictAboutTodoAnnotatedTests="true"
9+
colors="true"
10+
bootstrap="tests/bootstrap.php"
11+
>
12+
<testsuites>
13+
<testsuite name="Test Suite">
14+
<directory>tests</directory>
15+
</testsuite>
16+
</testsuites>
17+
<filter>
18+
<whitelist processUncoveredFilesFromWhitelist="true">
19+
<directory suffix=".php">src</directory>
20+
</whitelist>
21+
</filter>
22+
<logging>
23+
<log
24+
showOnlySummary="true"
25+
showUncoveredFiles="true"
26+
target="php://stdout"
27+
type="coverage-text"
28+
/>
29+
<log type="coverage-clover" target="temp/clover.xml"/>
30+
<log type="coverage-html" target="temp/coverage-html"/>
31+
</logging>
32+
</phpunit>

0 commit comments

Comments
 (0)