From 099ae192ee513382666c44c1d1808515c3eee131 Mon Sep 17 00:00:00 2001 From: Richard McDaniel Date: Fri, 17 Nov 2023 14:51:38 +0000 Subject: [PATCH] First commit --- .github/workflows/php.yml | 42 + .gitignore | 4 + LICENSE | 21 + README.md | 93 + composer.json | 34 + composer.lock | 2575 ++++++++++++++++++++++++++ ecs.php | 77 + phpstan.neon | 2 + phpunit.xml | 11 + rector.php | 30 + src/Action.php | 32 + src/ActionDataFilter.php | 16 + src/AuthDef.php | 23 + src/BaseObject.php | 211 +++ src/BasicPropsDef.php | 14 + src/BearerPropsDef.php | 12 + src/Branch.php | 15 + src/BranchTimeout.php | 12 + src/CallbackState.php | 44 + src/CallbackStateTimeout.php | 14 + src/ContinueAsDef.php | 17 + src/CorrelationDef.php | 12 + src/CronDef.php | 12 + src/DataInputSchema.php | 18 + src/DefaultConditionDef.php | 12 + src/End.php | 24 + src/EndDataCondition.php | 16 + src/EndEventCondition.php | 18 + src/Error.php | 17 + src/ErrorDef.php | 14 + src/EventBasedSwitchState.php | 39 + src/EventBasedSwitchStateTimeOut.php | 12 + src/EventDataFilter.php | 14 + src/EventDef.php | 30 + src/EventRef.php | 22 + src/EventState.php | 41 + src/EventStateTimeout.php | 14 + src/ForeachState.php | 52 + src/ForeachStateTimeout.php | 14 + src/FunctionDef.php | 18 + src/FunctionRef.php | 17 + src/InjectState.php | 41 + src/InjectStateTimeout.php | 10 + src/Metadata.php | 9 + src/OAuth2PropsDef.php | 34 + src/OnEvents.php | 18 + src/OperationState.php | 44 + src/OperationStateTimeout.php | 12 + src/ParallelState.php | 46 + src/ParallelStateTimeout.php | 12 + src/ProduceEventDef.php | 16 + src/RetryDef.php | 22 + src/Schedule.php | 14 + src/Serializable.php | 9 + src/Sleep.php | 12 + src/SleepState.php | 40 + src/SleepStateTimeout.php | 10 + src/StartDef.php | 12 + src/State.php | 50 + src/StateDataFilter.php | 12 + src/StateExecTimeout.php | 12 + src/SubFlowRef.php | 16 + src/Transition.php | 15 + src/TransitionDataCondition.php | 16 + src/TransitionEventCondition.php | 18 + src/Workflow.php | 113 ++ src/WorkflowExecTimeout.php | 14 + src/WorkflowTimeout.php | 18 + src/WorkflowValidator.php | 18 + tests/Fixtures/workflow.json | 37 + tests/Fixtures/workflow.yaml | 26 + tests/Unit/WorkflowTest.php | 96 + 72 files changed, 4537 insertions(+) create mode 100644 .github/workflows/php.yml create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 ecs.php create mode 100644 phpstan.neon create mode 100644 phpunit.xml create mode 100644 rector.php create mode 100644 src/Action.php create mode 100644 src/ActionDataFilter.php create mode 100644 src/AuthDef.php create mode 100644 src/BaseObject.php create mode 100644 src/BasicPropsDef.php create mode 100644 src/BearerPropsDef.php create mode 100644 src/Branch.php create mode 100644 src/BranchTimeout.php create mode 100644 src/CallbackState.php create mode 100644 src/CallbackStateTimeout.php create mode 100644 src/ContinueAsDef.php create mode 100644 src/CorrelationDef.php create mode 100644 src/CronDef.php create mode 100644 src/DataInputSchema.php create mode 100644 src/DefaultConditionDef.php create mode 100644 src/End.php create mode 100644 src/EndDataCondition.php create mode 100644 src/EndEventCondition.php create mode 100644 src/Error.php create mode 100644 src/ErrorDef.php create mode 100644 src/EventBasedSwitchState.php create mode 100644 src/EventBasedSwitchStateTimeOut.php create mode 100644 src/EventDataFilter.php create mode 100644 src/EventDef.php create mode 100644 src/EventRef.php create mode 100644 src/EventState.php create mode 100644 src/EventStateTimeout.php create mode 100644 src/ForeachState.php create mode 100644 src/ForeachStateTimeout.php create mode 100644 src/FunctionDef.php create mode 100644 src/FunctionRef.php create mode 100644 src/InjectState.php create mode 100644 src/InjectStateTimeout.php create mode 100644 src/Metadata.php create mode 100644 src/OAuth2PropsDef.php create mode 100644 src/OnEvents.php create mode 100644 src/OperationState.php create mode 100644 src/OperationStateTimeout.php create mode 100644 src/ParallelState.php create mode 100644 src/ParallelStateTimeout.php create mode 100644 src/ProduceEventDef.php create mode 100644 src/RetryDef.php create mode 100644 src/Schedule.php create mode 100644 src/Serializable.php create mode 100644 src/Sleep.php create mode 100644 src/SleepState.php create mode 100644 src/SleepStateTimeout.php create mode 100644 src/StartDef.php create mode 100644 src/State.php create mode 100644 src/StateDataFilter.php create mode 100644 src/StateExecTimeout.php create mode 100644 src/SubFlowRef.php create mode 100644 src/Transition.php create mode 100644 src/TransitionDataCondition.php create mode 100644 src/TransitionEventCondition.php create mode 100644 src/Workflow.php create mode 100644 src/WorkflowExecTimeout.php create mode 100644 src/WorkflowTimeout.php create mode 100644 src/WorkflowValidator.php create mode 100644 tests/Fixtures/workflow.json create mode 100644 tests/Fixtures/workflow.yaml create mode 100644 tests/Unit/WorkflowTest.php diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml new file mode 100644 index 0000000..6ff8bff --- /dev/null +++ b/.github/workflows/php.yml @@ -0,0 +1,42 @@ +name: PHP Composer + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Validate composer.json and composer.lock + run: composer validate --strict + + - name: Cache Composer packages + id: composer-cache + uses: actions/cache@v3 + with: + path: vendor + key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-php- + + - name: Install dependencies + run: composer install --prefer-dist --no-progress + + - name: Check coding style via ECS + run: vendor/bin/ecs check + + - name: Run static analysis via PHPStan + run: vendor/bin/phpstan --xdebug analyse src tests + + - name: Run test suite + run: composer run-script test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c1e3387 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.phpunit.cache/ +.phpunit.result.cache +composer.phar +/vendor/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1ad2fef --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 TaskValve + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b9cec39 --- /dev/null +++ b/README.md @@ -0,0 +1,93 @@ +# Serverless Workflow Specification - PHP SDK + +Provides the PHP API/SPI for the [Serverless Workflow Specification](https://github.com/serverlessworkflow/specification) + +With the SDK you can: +* Programmatically build workflow definitions +* Parse workflow JSON and YAML definitions +* Validate workflow definitions + +### Status + +Current SDK version conforms to the [Serverless Workflow specification v0.8](https://github.com/serverlessworkflow/specification/tree/0.8.x). + + +## Installation + +```bash +composer install taskvalve/serverless-workflow-php +``` + +## Build + +```php +use Serverless\Workflow\Action; +use Serverless\Workflow\ActionDataFilter; +use Serverless\Workflow\FunctionDef; +use Serverless\Workflow\FunctionRef; +use Serverless\Workflow\OperationState; +use Serverless\Workflow\Workflow; + +$workflow = new Workflow([ + 'id' => 'greeting', + 'name' => 'Greeting Workflow', + 'description' => 'Greet Someone', + 'version' => '1.0', + 'specVersion' => '0.8', + 'start' => 'Greet', + 'states' => [ + new OperationState([ + 'name' => 'Greet', + 'type' => 'operation', + 'actions' => [ + new Action([ + 'functionRef' => new FunctionRef([ + 'refName' => 'greetingFunction', + 'arguments' => [ + 'name' => '${ .person.name }', + ], + ]), + 'actionDataFilter' => new ActionDataFilter([ + 'results' => '${ .greeting }', + ]), + ]), + ], + 'end' => true, + ]), + ], + 'functions' => [ + new FunctionDef([ + 'name' => 'greetingFunction', + 'operation' => 'file://myapis/greetingapis.json#greeting', + ]), + ], +]); +``` + +## Parse + +### Convert from JSON/YAML source + +```php +$workflow = Workflow::fromJson(file_get_contents('workflow.json')); + +$workflow = Workflow::fromYaml(file_get_contents('workflow.yaml')); +``` + +### Convert to JSON/YAML + +```php +$json = $workflow->toJson(); + +$yaml = $workflow->toYaml(); +``` + +## Validate + +```php +use Serverless\Workflow\WorkflowValidator; + +WorkflowValidator::validate($workflow); +``` + +The `validate` method will raise an exception if the provided workflow does not comply with the specification. diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..28f39e4 --- /dev/null +++ b/composer.json @@ -0,0 +1,34 @@ +{ + "name": "taskvalve/serverless-workflow-php", + "description": "Provides the PHP API/SPI for the Serverless Workflow Specification.", + "type": "library", + "license": "MIT", + "autoload": { + "psr-4": { + "Serverless\\Workflow\\": "src/" + } + }, + "authors": [ + { + "name": "Richard McDaniel", + "email": "richard.lee.mcdaniel@gmail.com" + } + ], + "require-dev": { + "phpstan/phpstan": "^1.9", + "phpunit/phpunit": "^10.4", + "rector/rector": "^0.18.10", + "symplify/easy-coding-standard": "^11.1" + }, + "require": { + "symfony/yaml": "^6.3", + "phpdocumentor/reflection-docblock": "^5.3", + "swaggest/json-schema": "^0.12.42" + }, + "scripts": { + "rector": "vendor/bin/rector", + "ecs": "vendor/bin/ecs check --fix", + "stan": "vendor/bin/phpstan analyse src tests", + "test": "phpunit --testdox" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..dae61b2 --- /dev/null +++ b/composer.lock @@ -0,0 +1,2575 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "216a7e03db74b7e0da42085e4bd262a2", + "packages": [ + { + "name": "doctrine/deprecations", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/4f2d4f2836e7ec4e7a8625e75c6aa916004db931", + "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpstan/phpstan": "1.4.10 || 1.10.15", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "0.18.4", + "psr/log": "^1 || ^2 || ^3", + "vimeo/psalm": "4.30.0 || 5.12.0" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.2" + }, + "time": "2023-09-27T20:04:15+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.7.3", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419", + "reference": "3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.13" + }, + "require-dev": { + "ext-tokenizer": "*", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.3" + }, + "time": "2023-08-12T11:01:26+00:00" + }, + { + "name": "phplang/scope-exit", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/phplang/scope-exit.git", + "reference": "239b73abe89f9414aa85a7ca075ec9445629192b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phplang/scope-exit/zipball/239b73abe89f9414aa85a7ca075ec9445629192b", + "reference": "239b73abe89f9414aa85a7ca075ec9445629192b", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpLang\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD" + ], + "authors": [ + { + "name": "Sara Golemon", + "email": "pollita@php.net", + "homepage": "https://twitter.com/SaraMG", + "role": "Developer" + } + ], + "description": "Emulation of SCOPE_EXIT construct from C++", + "homepage": "https://github.com/phplang/scope-exit", + "keywords": [ + "cleanup", + "exit", + "scope" + ], + "support": { + "issues": "https://github.com/phplang/scope-exit/issues", + "source": "https://github.com/phplang/scope-exit/tree/master" + }, + "time": "2016-09-17T00:15:18+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "1.24.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "bcad8d995980440892759db0c32acae7c8e79442" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/bcad8d995980440892759db0c32acae7c8e79442", + "reference": "bcad8d995980440892759db0c32acae7c8e79442", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^4.15", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.5", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.2" + }, + "time": "2023-09-26T12:28:12+00:00" + }, + { + "name": "swaggest/json-diff", + "version": "v3.10.4", + "source": { + "type": "git", + "url": "https://github.com/swaggest/json-diff.git", + "reference": "f4e511708060ff7511a3743fab4aa484a062bcfb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swaggest/json-diff/zipball/f4e511708060ff7511a3743fab4aa484a062bcfb", + "reference": "f4e511708060ff7511a3743fab4aa484a062bcfb", + "shasum": "" + }, + "require": { + "ext-json": "*" + }, + "require-dev": { + "phperf/phpunit": "4.8.37" + }, + "type": "library", + "autoload": { + "psr-4": { + "Swaggest\\JsonDiff\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Viacheslav Poturaev", + "email": "vearutop@gmail.com" + } + ], + "description": "JSON diff/rearrange/patch/pointer library for PHP", + "support": { + "issues": "https://github.com/swaggest/json-diff/issues", + "source": "https://github.com/swaggest/json-diff/tree/v3.10.4" + }, + "time": "2022-11-09T13:21:05+00:00" + }, + { + "name": "swaggest/json-schema", + "version": "v0.12.42", + "source": { + "type": "git", + "url": "https://github.com/swaggest/php-json-schema.git", + "reference": "d23adb53808b8e2da36f75bc0188546e4cbe3b45" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swaggest/php-json-schema/zipball/d23adb53808b8e2da36f75bc0188546e4cbe3b45", + "reference": "d23adb53808b8e2da36f75bc0188546e4cbe3b45", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=5.4", + "phplang/scope-exit": "^1.0", + "swaggest/json-diff": "^3.8.2", + "symfony/polyfill-mbstring": "^1.19" + }, + "require-dev": { + "phperf/phpunit": "4.8.37" + }, + "suggest": { + "ext-mbstring": "For better performance" + }, + "type": "library", + "autoload": { + "psr-4": { + "Swaggest\\JsonSchema\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Viacheslav Poturaev", + "email": "vearutop@gmail.com" + } + ], + "description": "High definition PHP structures with JSON-schema based validation", + "support": { + "email": "vearutop@gmail.com", + "issues": "https://github.com/swaggest/php-json-schema/issues", + "source": "https://github.com/swaggest/php-json-schema/tree/v0.12.42" + }, + "time": "2023-09-12T14:43:42+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "42292d99c55abe617799667f454222c54c60e229" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", + "reference": "42292d99c55abe617799667f454222c54c60e229", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-07-28T09:04:16+00:00" + }, + { + "name": "symfony/yaml", + "version": "v6.3.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "3493af8a8dad7fa91c77fa473ba23ecd95334a92" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/3493af8a8dad7fa91c77fa473ba23ecd95334a92", + "reference": "3493af8a8dad7fa91c77fa473ba23ecd95334a92", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<5.4" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v6.3.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-11-06T10:58:05+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + } + ], + "packages-dev": [ + { + "name": "myclabs/deep-copy", + "version": "1.11.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2023-03-08T13:26:56+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.17.1", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" + }, + "time": "2023-08-13T19:53:39+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.10.41", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "c6174523c2a69231df55bdc65b61655e72876d76" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/c6174523c2a69231df55bdc65b61655e72876d76", + "reference": "c6174523c2a69231df55bdc65b61655e72876d76", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2023-11-05T12:57:57+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "10.1.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "84838eed9ded511f61dc3e8b5944a52d9017b297" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/84838eed9ded511f61dc3e8b5944a52d9017b297", + "reference": "84838eed9ded511f61dc3e8b5944a52d9017b297", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.15", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-text-template": "^3.0", + "sebastian/code-unit-reverse-lookup": "^3.0", + "sebastian/complexity": "^3.0", + "sebastian/environment": "^6.0", + "sebastian/lines-of-code": "^2.0", + "sebastian/version": "^4.0", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.1" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-11-15T13:31:15+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "4.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T06:24:48+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:56:09+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T14:07:24+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:57:52+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "10.4.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "cacd8b9dd224efa8eb28beb69004126c7ca1a1a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/cacd8b9dd224efa8eb28beb69004126c7ca1a1a1", + "reference": "cacd8b9dd224efa8eb28beb69004126c7ca1a1a1", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1.5", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-invoker": "^4.0", + "phpunit/php-text-template": "^3.0", + "phpunit/php-timer": "^6.0", + "sebastian/cli-parser": "^2.0", + "sebastian/code-unit": "^2.0", + "sebastian/comparator": "^5.0", + "sebastian/diff": "^5.0", + "sebastian/environment": "^6.0", + "sebastian/exporter": "^5.1", + "sebastian/global-state": "^6.0.1", + "sebastian/object-enumerator": "^5.0", + "sebastian/recursion-context": "^5.0", + "sebastian/type": "^4.0", + "sebastian/version": "^4.0" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.4-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.4.2" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2023-10-26T07:21:45+00:00" + }, + { + "name": "rector/rector", + "version": "0.18.10", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "f36bc0a707fd8af301df5108740ce41f9db8eded" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/f36bc0a707fd8af301df5108740ce41f9db8eded", + "reference": "f36bc0a707fd8af301df5108740ce41f9db8eded", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "phpstan/phpstan": "^1.10.35" + }, + "conflict": { + "rector/rector-doctrine": "*", + "rector/rector-downgrade-php": "*", + "rector/rector-phpunit": "*", + "rector/rector-symfony": "*" + }, + "bin": [ + "bin/rector" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "keywords": [ + "automation", + "dev", + "migration", + "refactoring" + ], + "support": { + "issues": "https://github.com/rectorphp/rector/issues", + "source": "https://github.com/rectorphp/rector/tree/0.18.10" + }, + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2023-11-16T19:42:21+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/efdc130dbbbb8ef0b545a994fd811725c5282cae", + "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:15+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:43+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:59:15+00:00" + }, + { + "name": "sebastian/comparator", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2db5010a484d53ebf536087a70b4a5423c102372" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372", + "reference": "2db5010a484d53ebf536087a70b4a5423c102372", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-14T13:18:12+00:00" + }, + { + "name": "sebastian/complexity", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "68cfb347a44871f01e33ab0ef8215966432f6957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68cfb347a44871f01e33ab0ef8215966432f6957", + "reference": "68cfb347a44871f01e33ab0ef8215966432f6957", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.10", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-09-28T11:50:59+00:00" + }, + { + "name": "sebastian/diff", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/912dc2fbe3e3c1e7873313cc801b100b6c68c87b", + "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-05-01T07:48:21+00:00" + }, + { + "name": "sebastian/environment", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/43c751b41d74f96cbbd4e07b7aec9675651e2951", + "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-04-11T05:39:26+00:00" + }, + { + "name": "sebastian/exporter", + "version": "5.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/64f51654862e0f5e318db7e9dcc2292c63cdbddc", + "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-09-24T13:22:09+00:00" + }, + { + "name": "sebastian/global-state", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4", + "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-07-19T07:19:23+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/649e40d279e243d985aa8fb6e74dd5bb28dc185d", + "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.10", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T09:25:50+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:08:32+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:06:18+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:05:40+00:00" + }, + { + "name": "sebastian/type", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:10:45+00:00" + }, + { + "name": "sebastian/version", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-07T11:34:05+00:00" + }, + { + "name": "symplify/easy-coding-standard", + "version": "11.5.0", + "source": { + "type": "git", + "url": "https://github.com/easy-coding-standard/easy-coding-standard.git", + "reference": "1d2400f7bfe92e3754ce71f0782f2c0521bade3d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/easy-coding-standard/easy-coding-standard/zipball/1d2400f7bfe92e3754ce71f0782f2c0521bade3d", + "reference": "1d2400f7bfe92e3754ce71f0782f2c0521bade3d", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "conflict": { + "friendsofphp/php-cs-fixer": "<3.0", + "squizlabs/php_codesniffer": "<3.6", + "symplify/coding-standard": "<11.3" + }, + "bin": [ + "bin/ecs" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Use Coding Standard with 0-knowledge of PHP-CS-Fixer and PHP_CodeSniffer", + "keywords": [ + "Code style", + "automation", + "fixer", + "static analysis" + ], + "support": { + "issues": "https://github.com/easy-coding-standard/easy-coding-standard/issues", + "source": "https://github.com/easy-coding-standard/easy-coding-standard/tree/11.5.0" + }, + "funding": [ + { + "url": "https://www.paypal.me/rectorphp", + "type": "custom" + }, + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2023-06-21T06:26:15+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/ecs.php b/ecs.php new file mode 100644 index 0000000..985f25b --- /dev/null +++ b/ecs.php @@ -0,0 +1,77 @@ +sets([SetList::PSR_12, SetList::SYMPLIFY, SetList::COMMON, SetList::CLEAN_CODE]); + + $ecsConfig->paths([ + __DIR__ . '/src', + __DIR__ . '/tests', + ]); + + $ecsConfig->ruleWithConfiguration(NoSuperfluousPhpdocTagsFixer::class, [ + 'allow_mixed' => true, + ]); + + $ecsConfig->ruleWithConfiguration(GeneralPhpdocAnnotationRemoveFixer::class, [ + 'annotations' => [ + 'throw', + 'throws', + 'author', + 'authors', + 'package', + 'group', + 'required', + 'phpstan-ignore-line', + 'phpstan-ignore-next-line', + ], + ]); + + $ecsConfig->rule(StaticLambdaFixer::class); + + $ecsConfig->skip([ + '*/Source/*', + '*/Fixture/*', + '*/Expected/*', + + // buggy - @todo fix on Symplify master + DocBlockLineLengthFixer::class, + + PhpdocTypesFixer::class => [ + // double to Double false positive + __DIR__ . '/rules/Php74/Rector/Double/RealToFloatTypeCastRector.php', + // skip for enum types + __DIR__ . '/rules/Php70/Rector/MethodCall/ThisCallOnStaticMethodToStaticCallRector.php', + ], + + // breaking and handled better by Rector PHPUnit code quality set, removed in symplify dev-main + PhpUnitStrictFixer::class, + + // skip add space on &$variable + FunctionTypehintSpaceFixer::class => [ + __DIR__ . '/src/PhpParser/Printer/BetterStandardPrinter.php', + __DIR__ . '/src/DependencyInjection/Loader/Configurator/RectorServiceConfigurator.php', + __DIR__ . '/rules/Php70/EregToPcreTransformer.php', + ], + + AssignmentInConditionSniff::class . '.FoundInWhileCondition', + + // null on purpose as no change + PhpdocNoEmptyReturnFixer::class => [ + __DIR__ . '/rules/DeadCode/Rector/ConstFetch/RemovePhpVersionIdCheckRector.php', + ], + ]); +}; \ No newline at end of file diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..e2219f5 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,2 @@ +parameters: + level: 6 diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..55b3010 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,11 @@ + + + + + ./tests/Unit + + + + + + diff --git a/rector.php b/rector.php new file mode 100644 index 0000000..8cdce60 --- /dev/null +++ b/rector.php @@ -0,0 +1,30 @@ +paths([ + __DIR__ . '/src', + __DIR__ . '/tests' + ]); + + $rectorConfig->parallel(240); + + $rectorConfig->phpVersion(PhpVersion::PHP_81); + + $rectorConfig->sets([ + LevelSetList::UP_TO_PHP_81, + SetList::CODE_QUALITY, + SetList::DEAD_CODE, + SetList::PRIVATIZATION, + SetList::NAMING, + SetList::TYPE_DECLARATION, + SetList::EARLY_RETURN, + SetList::CODING_STYLE, + ]); +}; diff --git a/src/Action.php b/src/Action.php new file mode 100644 index 0000000..e7ff95e --- /dev/null +++ b/src/Action.php @@ -0,0 +1,32 @@ +scheme ??= 'basic'; + } +} diff --git a/src/BaseObject.php b/src/BaseObject.php new file mode 100644 index 0000000..5a32537 --- /dev/null +++ b/src/BaseObject.php @@ -0,0 +1,211 @@ +initializeProperties($data); + } + + /** + * @param mixed[] $data + */ + private function initializeProperties(array $data): void + { + $reflectionClass = new ReflectionClass($this); + foreach ($data as $key => $value) { + if ($reflectionClass->hasProperty($key)) { + $property = $reflectionClass->getProperty($key); + $this->assignValue($property, $value); + } + } + } + + private function assignValue(ReflectionProperty $reflectionProperty, mixed $value): void + { + $type = $reflectionProperty->getType(); + + if (! empty($this->getTypeFromProperty($reflectionProperty))) { + $this->handleDocCommentType($reflectionProperty, $value); + } elseif ($type instanceof ReflectionUnionType) { + $this->handleUnionType($reflectionProperty, $value, $type->getTypes()); + } elseif ($type instanceof ReflectionNamedType) { + $this->handleNamedType($reflectionProperty, $value, $type); + } + } + + /** + * @param mixed[] $types + */ + private function handleUnionType(ReflectionProperty $reflectionProperty, mixed $value, array $types): void + { + foreach ($types as $type) { + if ($this->canInstantiateType($type, $value)) { + $typeName = $type->getName(); + $this->instantiateAndSetValue($reflectionProperty, $value, $typeName); + return; + } + } + } + + private function handleNamedType( + ReflectionProperty $reflectionProperty, + mixed $value, + ReflectionNamedType $reflectionNamedType + ): void { + $typeName = $reflectionNamedType->getName(); + $this->instantiateAndSetValue($reflectionProperty, $value, $typeName); + } + + private function handleDocCommentType(ReflectionProperty $reflectionProperty, mixed $value): void + { + $typeHints = $this->getTypeFromProperty($reflectionProperty); + if (! empty($typeHints)) { + foreach ($typeHints as $typeHint) { + if ($this->canInstantiateTypeFromDoc($typeHint, $value)) { + $this->instantiateAndSetValue($reflectionProperty, $value, $typeHint); + return; + } + } + } + + $reflectionProperty->setValue($this, $value); + } + + /** + * @return string[] + */ + private function getTypeFromProperty(ReflectionProperty $reflectionProperty): array + { + $docComment = $reflectionProperty->getDocComment(); + if ($docComment === false) { + return []; + } + + $docBlockFactory = DocBlockFactory::createInstance(); + $docblock = $docBlockFactory->create( + $docComment, + (new ContextFactory())->createFromReflector($reflectionProperty) + ); + + $varTags = $docblock->getTagsByName('var'); + if ($varTags !== []) { + return array_map('trim', explode('|', $varTags[0]->__toString())); + } + + return []; + } + + private function canInstantiateTypeFromDoc(string $typeName, mixed $value): bool + { + if (str_contains($typeName, '[]')) { + return is_array($value); + } + return class_exists($typeName) || is_scalar($value); + } + + private function canInstantiateType(ReflectionNamedType $reflectionNamedType, mixed $value): bool + { + $typeName = $reflectionNamedType->getName(); + + if ($typeName === 'bool') { + return is_bool($value); + } + + if ($typeName === 'string') { + return is_string($value); + } + + if ($typeName === 'array') { + return is_array($value); + } + + if (! class_exists($typeName)) { + return false; + } + + if (is_a($value, $typeName)) { + return true; + } + + if (! is_array($value)) { + return false; + } + + $reflectionClass = new ReflectionClass($typeName); + $properties = array_map( + static fn (ReflectionProperty $property): string => $property->getName(), + $reflectionClass->getProperties(ReflectionProperty::IS_PUBLIC) + ); + + foreach (array_keys($value) as $key) { + if (! in_array($key, $properties, true)) { + return false; + } + } + + return true; + } + + private function instantiateAndSetValue( + ReflectionProperty $reflectionProperty, + mixed $value, + string $typeName + ): void { + if (str_contains($typeName, '[]')) { + $singleTypeName = str_replace('[]', '', $typeName); + $objects = []; + foreach ($value as $item) { + if ($singleTypeName === '\\' . \Serverless\Workflow\State::class && is_array($item)) { + foreach (glob(__DIR__ . '/*.php') as $filename) { + $class = '\\Serverless\\Workflow\\' . basename($filename, '.php'); + if (class_exists($class) && is_subclass_of($class, '\\' . \Serverless\Workflow\State::class)) { + $reflection = new ReflectionClass($class); + if ($reflection->hasProperty('type')) { + $instance = $reflection->newInstance([]); + $typeValue = $reflection->getProperty('type') + ->getValue($instance); + if ($typeValue === $item['type']) { + $singleTypeName = $class; + break; + } + } + } + } + } + + if (is_a($item, $singleTypeName)) { + $objects[] = $item; + } else { + $objects[] = new $singleTypeName($item); + } + } + $reflectionProperty->setValue($this, $objects); + } elseif (class_exists($typeName)) { + if (is_a($value, $typeName)) { + $reflectionProperty->setValue($this, $value); + } else { + $reflectionProperty->setValue($this, new $typeName($value)); + } + } else { + $reflectionProperty->setValue($this, $value); + } + } +} diff --git a/src/BasicPropsDef.php b/src/BasicPropsDef.php new file mode 100644 index 0000000..133f34f --- /dev/null +++ b/src/BasicPropsDef.php @@ -0,0 +1,14 @@ +usedForCompensation ??= false; + $this->type ??= 'callback'; + } +} diff --git a/src/CallbackStateTimeout.php b/src/CallbackStateTimeout.php new file mode 100644 index 0000000..997c746 --- /dev/null +++ b/src/CallbackStateTimeout.php @@ -0,0 +1,14 @@ +failOnValidationErrors ??= false; + } +} diff --git a/src/DefaultConditionDef.php b/src/DefaultConditionDef.php new file mode 100644 index 0000000..21d520d --- /dev/null +++ b/src/DefaultConditionDef.php @@ -0,0 +1,12 @@ +terminate ??= false; + $this->compensate ??= false; + } +} diff --git a/src/EndDataCondition.php b/src/EndDataCondition.php new file mode 100644 index 0000000..7007e9c --- /dev/null +++ b/src/EndDataCondition.php @@ -0,0 +1,16 @@ +usedForCompensation ??= false; + $this->type ??= 'switch'; + } +} diff --git a/src/EventBasedSwitchStateTimeOut.php b/src/EventBasedSwitchStateTimeOut.php new file mode 100644 index 0000000..9a240fa --- /dev/null +++ b/src/EventBasedSwitchStateTimeOut.php @@ -0,0 +1,12 @@ +kind ??= 'consumed'; + $this->dataOnly ??= true; + } +} diff --git a/src/EventRef.php b/src/EventRef.php new file mode 100644 index 0000000..f8a2e5a --- /dev/null +++ b/src/EventRef.php @@ -0,0 +1,22 @@ +exclusive ??= true; + $this->type ??= 'event'; + } +} diff --git a/src/EventStateTimeout.php b/src/EventStateTimeout.php new file mode 100644 index 0000000..89c034c --- /dev/null +++ b/src/EventStateTimeout.php @@ -0,0 +1,14 @@ +usedForCompensation ??= false; + $this->mode ??= 'parallel'; + $this->type ??= 'foreach'; + } +} diff --git a/src/ForeachStateTimeout.php b/src/ForeachStateTimeout.php new file mode 100644 index 0000000..4d6ecea --- /dev/null +++ b/src/ForeachStateTimeout.php @@ -0,0 +1,14 @@ +usedForCompensation ??= false; + $this->type ??= 'inject'; + } +} diff --git a/src/InjectStateTimeout.php b/src/InjectStateTimeout.php new file mode 100644 index 0000000..42a6049 --- /dev/null +++ b/src/InjectStateTimeout.php @@ -0,0 +1,10 @@ +type ??= 'operation'; + $this->actionMode ??= 'sequential'; + $this->usedForCompensation ??= false; + } +} diff --git a/src/OperationStateTimeout.php b/src/OperationStateTimeout.php new file mode 100644 index 0000000..96735b2 --- /dev/null +++ b/src/OperationStateTimeout.php @@ -0,0 +1,12 @@ +completionType ??= 'allOf'; + $this->usedForCompensation ??= false; + $this->type ??= 'parallel'; + } +} diff --git a/src/ParallelStateTimeout.php b/src/ParallelStateTimeout.php new file mode 100644 index 0000000..a8f21d2 --- /dev/null +++ b/src/ParallelStateTimeout.php @@ -0,0 +1,12 @@ +usedForCompensation ??= false; + $this->type ??= 'sleep'; + } +} diff --git a/src/SleepStateTimeout.php b/src/SleepStateTimeout.php new file mode 100644 index 0000000..494256a --- /dev/null +++ b/src/SleepStateTimeout.php @@ -0,0 +1,10 @@ +type === 'event'; + } + + public function isOperationState(): bool + { + return $this->type === 'operation'; + } + + public function isSwitchState(): bool + { + return $this->type === 'switch'; + } + + public function isSleepState(): bool + { + return $this->type === 'sleep'; + } + + public function isParallelState(): bool + { + return $this->type === 'parallel'; + } + + public function isInjectState(): bool + { + return $this->type === 'inject'; + } + + public function isForeachState(): bool + { + return $this->type === 'foreach'; + } + + public function isCallbackState(): bool + { + return $this->type === 'callback'; + } +} diff --git a/src/StateDataFilter.php b/src/StateDataFilter.php new file mode 100644 index 0000000..bd7ce57 --- /dev/null +++ b/src/StateDataFilter.php @@ -0,0 +1,12 @@ +keepActive ??= true; + } + + /** + * @return mixed[] + */ + public function toArray(): array + { + $convertObjectsToArray = static function ($input) use (&$convertObjectsToArray) { + if (is_object($input)) { + $input = get_object_vars($input); + } + if (is_array($input)) { + $input = array_filter($input, static fn ($value): bool => $value !== null); + + foreach ($input as $key => $value) { + $input[$key] = $convertObjectsToArray($value); + } + } + return $input; + }; + + return $convertObjectsToArray($this); + } + + public function toJson(): string + { + return json_encode($this->toArray(), JSON_PRETTY_PRINT) ?: ''; + } + + public static function fromJson(string $json): self + { + return new self(json_decode($json, true, 512, JSON_THROW_ON_ERROR)); + } + + public function toYaml(): string + { + return Yaml::dump($this->toArray(), 100, 2, Yaml::DUMP_OBJECT_AS_MAP); + } + + public static function fromYaml(string $yaml): self + { + return new self(Yaml::parse($yaml)); + } +} diff --git a/src/WorkflowExecTimeout.php b/src/WorkflowExecTimeout.php new file mode 100644 index 0000000..aafa586 --- /dev/null +++ b/src/WorkflowExecTimeout.php @@ -0,0 +1,14 @@ +in(json_decode((string) $workflow->toJson(), null, 512, JSON_THROW_ON_ERROR)); + } +} diff --git a/tests/Fixtures/workflow.json b/tests/Fixtures/workflow.json new file mode 100644 index 0000000..73c3978 --- /dev/null +++ b/tests/Fixtures/workflow.json @@ -0,0 +1,37 @@ +{ + "id": "greeting", + "name": "Greeting Workflow", + "description": "Greet Someone", + "version": "1.0", + "start": "Greet", + "specVersion": "0.8", + "keepActive": true, + "functions": [ + { + "name": "greetingFunction", + "operation": "file:\/\/myapis\/greetingapis.json#greeting" + } + ], + "states": [ + { + "type": "operation", + "name": "Greet", + "end": true, + "actionMode": "sequential", + "actions": [ + { + "functionRef": { + "refName": "greetingFunction", + "arguments": { + "name": "${ .person.name }" + } + }, + "actionDataFilter": { + "results": "${ .greeting }" + } + } + ], + "usedForCompensation": false + } + ] +} \ No newline at end of file diff --git a/tests/Fixtures/workflow.yaml b/tests/Fixtures/workflow.yaml new file mode 100644 index 0000000..b28fb98 --- /dev/null +++ b/tests/Fixtures/workflow.yaml @@ -0,0 +1,26 @@ +id: greeting +name: 'Greeting Workflow' +description: 'Greet Someone' +version: '1.0' +start: Greet +specVersion: '0.8' +keepActive: true +functions: + - + name: greetingFunction + operation: 'file://myapis/greetingapis.json#greeting' +states: + - + type: operation + name: Greet + end: true + actionMode: sequential + actions: + - + functionRef: + refName: greetingFunction + arguments: + name: '${ .person.name }' + actionDataFilter: + results: '${ .greeting }' + usedForCompensation: false diff --git a/tests/Unit/WorkflowTest.php b/tests/Unit/WorkflowTest.php new file mode 100644 index 0000000..9c2f90c --- /dev/null +++ b/tests/Unit/WorkflowTest.php @@ -0,0 +1,96 @@ +json = file_get_contents(__DIR__ . '/../Fixtures/workflow.json'); + $this->yaml = file_get_contents(__DIR__ . '/../Fixtures/workflow.yaml'); + $this->workflow = Workflow::fromYaml($this->yaml); + } + + public function testBuild(): void + { + $workflow = new Workflow([ + 'id' => 'greeting', + 'name' => 'Greeting Workflow', + 'description' => 'Greet Someone', + 'version' => '1.0', + 'specVersion' => '0.8', + 'start' => 'Greet', + 'states' => [ + new OperationState([ + 'name' => 'Greet', + 'type' => 'operation', + 'actions' => [ + new Action([ + 'functionRef' => new FunctionRef([ + 'refName' => 'greetingFunction', + 'arguments' => [ + 'name' => '${ .person.name }', + ], + ]), + 'actionDataFilter' => new ActionDataFilter([ + 'results' => '${ .greeting }', + ]), + ]), + ], + 'end' => true, + ]), + ], + 'functions' => [ + new FunctionDef([ + 'name' => 'greetingFunction', + 'operation' => 'file://myapis/greetingapis.json#greeting', + ]), + ], + ]); + $this->assertEquals($this->workflow, $workflow); + } + + public function testToJson(): void + { + $this->assertSame($this->json, $this->workflow->toJson()); + } + + public function testFromJson(): void + { + $workflow = Workflow::fromJson($this->json); + $this->assertEquals($this->workflow, $workflow); + } + + public function testToYaml(): void + { + $this->assertSame($this->yaml, $this->workflow->toYaml()); + } + + public function testFromYaml(): void + { + $workflow = Workflow::fromYaml($this->yaml); + $this->assertEquals($this->workflow, $workflow); + } + + public function testValidate(): void + { + $this->expectNotToPerformAssertions(); + WorkflowValidator::validate($this->workflow); + } +}