[
  {
    "path": ".gitattributes",
    "content": ".* export-ignore\n*.md export-ignore\ntests export-ignore\n"
  },
  {
    "path": ".gitignore",
    "content": ".buildpath\n.php_cs.cache\ncomposer.phar\ncomposer.lock\nphpunit.xml\nvendor/\ncoverage/\n"
  },
  {
    "path": ".php_cs.dist",
    "content": "<?php\n\n$finder = PhpCsFixer\\Finder::create()\n    ->in(__DIR__)\n    ->exclude('Tests/Functional/cache')\n;\n\nreturn PhpCsFixer\\Config::create()\n    ->setRules([\n        '@Symfony' => true,\n        'ordered_imports' => true,\n        'phpdoc_order' => true,\n        'header_comment' => [\n            'header' => <<<HEADER\nThis file is part of the Swagger package.\n\n(c) EXSyst\n\nFor the full copyright and license information, please view the LICENSE\nfile that was distributed with this source code.\nHEADER\n        ],\n    ])\n    ->setFinder($finder)\n;\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: php\n\nphp:\n  - 7.0\n  - 7.1\n  - 7.2\n  - 7.3\n  - 7.4\n\nsudo: false\n\ncache:\n  directories:\n    - $HOME/.composer/cache\n\nbranches:\n  only:\n    - master\n    - /^\\d+\\.\\d+$/\n\nmatrix:\n  fast_finish: true\n  include:\n    - php: 7.0\n      env: COMPOSER_FLAGS=\"--prefer-lowest\"\n    - php: 7.4\n      env: COMPOSER_FLAGS=\"--prefer-lowest\"\n\nbefore_install:\n  - composer self-update\n\ninstall: composer update $COMPOSER_FLAGS\n\nscript: ./phpunit\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015 Thomas Gossmann\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
  },
  {
    "path": "README.md",
    "content": "# Swagger\n\n[![Build Status](https://travis-ci.org/GuilhemN/swagger.svg?branch=master)](https://travis-ci.org/GuilhemN/swagger)\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/EXSyst/Swagger/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/EXSyst/Swagger)\n[![Code Coverage](https://scrutinizer-ci.com/g/EXSyst/Swagger/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/EXSyst/Swagger)\n\nA php library to manipulate [Swagger](http://Swagger.io)/[Open API](https://openapis.org) specifications.\n\n## Installation\n\n```\ncomposer require EXSyst/Swagger\n```\n\n## Usage\n\nRead an `api.json` file:\n\n```php\n$swagger = Swagger::fromFile('api.json');\n\n// or\n\n$swagger = new Swagger($array);\n```\n\n### Collections\n\nThere are two major collections: `Paths` and `Definitions`. The API is similar for both:\n\n```php\n$paths = $swagger->getPaths();\n$p = new Path('/user');\n\nforeach ($paths as $path) {\n\t// adding\n\t$paths->add($a);\n\t\n\t// retrieving\n\tif ($paths->has('/user') || $paths->contains($p)) {\n\t\t$path = $paths->get('/user');\n\t}\n\t\n\t// removing\n\t$paths->remove('/user');\n}\n```\n\n### Models\n\nThere are a lot of models, e.g. the mentioned `Path` above. The API is well written, so it works with the auto-completion of your IDE. It is straight forward and uses the same naming scheme as the OpenAPI specification.\n\n\n## Contributing\n\nFeel free to fork and submit a pull request (don't forget the tests) and I am happy to merge.\n\n\n"
  },
  {
    "path": "composer.json",
    "content": "{\n\t\"name\" : \"exsyst/swagger\",\n\t\"description\" : \"A php library to manipulate Swagger specifications\",\n\t\"type\" : \"library\",\n\t\"license\" : \"MIT\",\n\t\"authors\" : [\n\t\t{\n\t\t\t\"name\" : \"Guilhem Niot\",\n\t\t\t\"email\" : \"guilhem@gniot.fr\"\n\t\t}\n\t],\n\t\"autoload\" : {\n\t\t\"psr-4\" : {\n\t\t\t\"EXSyst\\\\Component\\\\Swagger\\\\\" : \"src/\"\n\t\t}\n\t},\n\t\"autoload-dev\" : {\n\t\t\"psr-4\" : {\n\t\t\t\"EXSyst\\\\Component\\\\Swagger\\\\tests\\\\\" : \"tests/\"\n\t\t}\n\t},\n\t\"require\" : {\n\t\t\"php\" : \"^7.0|^8.0\"\n\t},\n\t\"require-dev\" : {\n\t\t\"symfony/phpunit-bridge\": \"^4.1.8|^5.0\"\n\t}\n}\n"
  },
  {
    "path": "phpunit",
    "content": "#!/usr/bin/env php\n<?php\nif (!file_exists(__DIR__.'/vendor/symfony/phpunit-bridge/bin/simple-phpunit')) {\n    echo \"Unable to find the `simple-phpunit` script in `vendor/symfony/phpunit-bridge/bin/`.\\nPlease run `composer update` before running this command.\\n\";\n    exit(1);\n}\nputenv('SYMFONY_PHPUNIT_DIR='.__DIR__.'/.phpunit');\nrequire __DIR__.'/vendor/symfony/phpunit-bridge/bin/simple-phpunit';\n"
  },
  {
    "path": "phpunit.xml.dist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!-- https://phpunit.de/manual/6.5/en/appendixes.configuration.html -->\n<phpunit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:noNamespaceSchemaLocation=\"vendor/phpunit/phpunit/phpunit.xsd\"\n         colors=\"true\"\n         bootstrap=\"vendor/autoload.php\"\n>\n    <php>\n        <ini name=\"error_reporting\" value=\"-1\" />\n    </php>\n\n    <testsuites>\n        <testsuite name=\"Project Test Suite\">\n            <directory>tests</directory>\n        </testsuite>\n    </testsuites>\n\n    <filter>\n        <whitelist>\n            <directory>.</directory>\n            <exclude>\n                <directory>tests</directory>\n                <directory>vendor</directory>\n            </exclude>\n        </whitelist>\n    </filter>\n</phpunit>\n"
  },
  {
    "path": "src/AbstractModel.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger;\n\n/**\n * @internal\n */\nabstract class AbstractModel\n{\n    const REQUIRED = true;\n\n    public function merge($data, $overwrite = false)\n    {\n        return $this->doMerge($this->normalize($data), $overwrite);\n    }\n\n    public function toArray()\n    {\n        $return = [];\n        foreach ($this->doExport() as $key => $value) {\n            $value = $this->resolve($value);\n            if (null === $value) {\n                continue;\n            }\n\n            $return[$key] = $value;\n        }\n\n        if (method_exists($this, 'getExtensions')) {\n            foreach ($this->getExtensions() as $name => $value) {\n                $return['x-'.$name] = $value;\n            }\n        }\n\n        if (is_array($return) && 0 === count($return) && !static::REQUIRED) {\n            $return = null;\n        }\n\n        return $return;\n    }\n\n    abstract protected function doMerge($data, $overwrite = false);\n\n    protected function normalize($data)\n    {\n        if ($data instanceof \\stdClass || $data instanceof \\ArrayAccess) {\n            return (array) $data;\n        }\n\n        return $data;\n    }\n\n    private function resolve($value)\n    {\n        if (is_array($value)) {\n            foreach ($value as &$v) {\n                $v = $this->resolve($v);\n            }\n        } elseif ($value instanceof self) {\n            $value = $value->toArray();\n        }\n\n        return $value;\n    }\n}\n"
  },
  {
    "path": "src/Collections/Definitions.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Collections;\n\nuse EXSyst\\Component\\Swagger\\AbstractModel;\nuse EXSyst\\Component\\Swagger\\Schema;\n\nfinal class Definitions extends AbstractModel implements \\IteratorAggregate\n{\n    const REQUIRED = false;\n\n    private $definitions = [];\n\n    public function __construct($data = [])\n    {\n        $this->merge($data);\n    }\n\n    protected function doMerge($data, $overwrite = false)\n    {\n        foreach ($data as $name => $schema) {\n            $this->get($name)->merge($schema, $overwrite);\n        }\n    }\n\n    protected function doExport(): array\n    {\n        return $this->definitions;\n    }\n\n    /**\n     * Returns the schema for the given field.\n     */\n    public function get(string $name): Schema\n    {\n        if (!$this->has($name)) {\n            $this->set($name, new Schema());\n        }\n\n        return $this->definitions[$name];\n    }\n\n    /**\n     * Sets the field.\n     */\n    public function set(string $name, Schema $schema): self\n    {\n        $this->definitions[$name] = $schema;\n\n        return $this;\n    }\n\n    /**\n     * Removes the given field.\n     */\n    public function remove(string $name): self\n    {\n        unset($this->definitions[$name]);\n\n        return $this;\n    }\n\n    /**\n     * Returns definitions has a schema with the given name.\n     */\n    public function has(string $name): bool\n    {\n        return isset($this->definitions[$name]);\n    }\n\n    public function getIterator(): \\ArrayIterator\n    {\n        return new \\ArrayIterator($this->definitions);\n    }\n}\n"
  },
  {
    "path": "src/Collections/Headers.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Collections;\n\nuse EXSyst\\Component\\Swagger\\AbstractModel;\nuse EXSyst\\Component\\Swagger\\Header;\n\nfinal class Headers extends AbstractModel implements \\IteratorAggregate\n{\n    const REQUIRED = false;\n\n    private $headers = [];\n\n    public function __construct($data = [])\n    {\n        $this->merge($data);\n    }\n\n    protected function doMerge($data, $overwrite = false)\n    {\n        foreach ($data as $name => $header) {\n            $this->get($name)->merge($header, $overwrite);\n        }\n    }\n\n    protected function doExport(): array\n    {\n        return $this->headers;\n    }\n\n    /**\n     * Returns whether a header with the given name exists.\n     */\n    public function has(string $header): bool\n    {\n        return isset($this->headers[$header]);\n    }\n\n    /**\n     * Returns the header info for the given code.\n     */\n    public function get($header): Header\n    {\n        if (!$this->has($header)) {\n            $this->set($header, new Header());\n        }\n\n        return $this->headers[$header];\n    }\n\n    /**\n     * Sets the header.\n     */\n    public function set(string $name, Header $header): self\n    {\n        $this->headers[$name] = $header;\n\n        return $this;\n    }\n\n    /**\n     * Removes the given header.\n     */\n    public function remove(string $header): self\n    {\n        unset($this->headers[$header]);\n\n        return $this;\n    }\n\n    public function getIterator(): \\ArrayIterator\n    {\n        return new \\ArrayIterator($this->headers);\n    }\n}\n"
  },
  {
    "path": "src/Collections/Parameters.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Collections;\n\nuse EXSyst\\Component\\Swagger\\AbstractModel;\nuse EXSyst\\Component\\Swagger\\Parameter;\nuse EXSyst\\Component\\Swagger\\Parts\\RefPart;\n\nfinal class Parameters extends AbstractModel implements \\IteratorAggregate\n{\n    const REQUIRED = false;\n\n    use RefPart;\n\n    private $parameters = [];\n\n    public function __construct($data = [])\n    {\n        $this->merge($data);\n    }\n\n    protected function doMerge($data, $overwrite = false)\n    {\n        $this->mergeRef($data, $overwrite);\n        if (!$this->hasRef()) {\n            foreach ($data as $parameter) {\n                $this->add(new Parameter($parameter));\n            }\n        }\n    }\n\n    protected function doExport(): array\n    {\n        if ($this->hasRef()) {\n            return ['$ref' => $this->getRef()];\n        }\n\n        return array_values($this->parameters);\n    }\n\n    /**\n     * Searches whether a parameter with the given unique combination exists.\n     */\n    public function has(string $name, string $in = null): bool\n    {\n        $id = $in ? $name.'/'.$in : $name;\n\n        return isset($this->parameters[$id]);\n    }\n\n    public function get(string $name, string $in = null): Parameter\n    {\n        if (!$this->has($name, $in)) {\n            $this->add(\n                new Parameter(['name' => $name, 'in' => $in])\n            );\n        }\n\n        $id = $in ? $name.'/'.$in : $name;\n\n        return $this->parameters[$id];\n    }\n\n    /**\n     * Adds a parameter.\n     */\n    public function add(Parameter $parameter): self\n    {\n        $this->parameters[$this->getIdentifier($parameter)] = $parameter;\n\n        return $this;\n    }\n\n    /**\n     * Removes a parameter.\n     */\n    public function remove(Parameter $parameter): self\n    {\n        unset($this->parameters[$this->getIdentifier($parameter)]);\n\n        return $this;\n    }\n\n    private function getIdentifier(Parameter $parameter)\n    {\n        if ($parameter->hasRef()) {\n            return $parameter->getRef();\n        }\n\n        return $parameter->getName().'/'.$parameter->getIn();\n    }\n\n    public function getIterator(): \\ArrayIterator\n    {\n        return new \\ArrayIterator(array_values($this->parameters));\n    }\n}\n"
  },
  {
    "path": "src/Collections/Paths.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Collections;\n\nuse EXSyst\\Component\\Swagger\\AbstractModel;\nuse EXSyst\\Component\\Swagger\\Parts\\ExtensionPart;\nuse EXSyst\\Component\\Swagger\\Path;\n\nfinal class Paths extends AbstractModel implements \\IteratorAggregate\n{\n    const REQUIRED = false;\n\n    use ExtensionPart;\n\n    private $paths = [];\n\n    public function __construct($data = [])\n    {\n        $this->merge($data);\n    }\n\n    protected function doMerge($data, $overwrite = false)\n    {\n        foreach ($data as $key => $path) {\n            if (0 !== strpos($key, 'x-')) {\n                $this->get($key)->merge($path, $overwrite);\n            }\n        }\n\n        $this->mergeExtensions($data, $overwrite);\n    }\n\n    protected function doExport(): array\n    {\n        return $this->paths;\n    }\n\n    /**\n     * Returns whether a path with the given name exists.\n     */\n    public function has(string $path): bool\n    {\n        return isset($this->paths[$path]);\n    }\n\n    /**\n     * Returns the path info for the given path.\n     */\n    public function get(string $path): Path\n    {\n        if (!$this->has($path)) {\n            $this->set($path, new Path());\n        }\n\n        return $this->paths[$path];\n    }\n\n    /**\n     * Sets the path.\n     */\n    public function set(string $path, Path $model): self\n    {\n        $this->paths[$path] = $model;\n\n        return $this;\n    }\n\n    /**\n     * Removes the given path.\n     */\n    public function remove(string $path): self\n    {\n        unset($this->paths[$path]);\n\n        return $this;\n    }\n\n    public function getIterator(): \\ArrayIterator\n    {\n        return new \\ArrayIterator($this->paths);\n    }\n}\n"
  },
  {
    "path": "src/Collections/Responses.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Collections;\n\nuse EXSyst\\Component\\Swagger\\AbstractModel;\nuse EXSyst\\Component\\Swagger\\Parts\\ExtensionPart;\nuse EXSyst\\Component\\Swagger\\Response;\n\nfinal class Responses extends AbstractModel implements \\IteratorAggregate\n{\n    use ExtensionPart;\n\n    private $responses = [];\n\n    public function __construct($data = [])\n    {\n        $this->merge($data);\n    }\n\n    protected function doMerge($data, $overwrite = false)\n    {\n        $this->mergeExtensions($data, $overwrite);\n\n        foreach ($data as $code => $response) {\n            if (0 !== strpos($code, 'x-')) {\n                $this->set($code, new Response($response));\n            }\n        }\n    }\n\n    protected function doExport(): array\n    {\n        return $this->responses;\n    }\n\n    /**\n     * Returns whether the given response exists.\n     */\n    public function has($code): bool\n    {\n        return isset($this->responses[$code]);\n    }\n\n    /**\n     * Returns the response info for the given code.\n     */\n    public function get($code): Response\n    {\n        if (!$this->has($code)) {\n            $this->set($code, new Response());\n        }\n\n        return $this->responses[$code];\n    }\n\n    /**\n     * Sets the response.\n     */\n    public function set($code, Response $response): self\n    {\n        $this->responses[$code] = $response;\n\n        return $this;\n    }\n\n    /**\n     * Removes the given response.\n     */\n    public function remove($code): self\n    {\n        unset($this->responses[$code]);\n\n        return $this;\n    }\n\n    public function getIterator(): \\ArrayIterator\n    {\n        return new \\ArrayIterator($this->responses);\n    }\n}\n"
  },
  {
    "path": "src/Contact.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger;\n\nuse EXSyst\\Component\\Swagger\\Parts\\ExtensionPart;\nuse EXSyst\\Component\\Swagger\\Util\\MergeHelper;\n\nfinal class Contact extends AbstractModel\n{\n    const REQUIRED = false;\n\n    use ExtensionPart;\n\n    /** @var string */\n    private $name;\n\n    /** @var string */\n    private $url;\n\n    /** @var string */\n    private $email;\n\n    public function __construct($data = [])\n    {\n        $this->merge($data);\n    }\n\n    protected function doMerge($data, $overwrite = false)\n    {\n        MergeHelper::mergeFields($this->name, $data['name'] ?? null, $overwrite);\n        MergeHelper::mergeFields($this->url, $data['url'] ?? null, $overwrite);\n        MergeHelper::mergeFields($this->email, $data['email'] ?? null, $overwrite);\n\n        $this->mergeExtensions($data, $overwrite);\n    }\n\n    protected function doExport(): array\n    {\n        return [\n            'name' => $this->name,\n            'url' => $this->url,\n            'email' => $this->email,\n        ];\n    }\n\n    /**\n     * @return string\n     */\n    public function getName()\n    {\n        return $this->name;\n    }\n\n    /**\n     * @param string $name\n     */\n    public function setName($name): self\n    {\n        $this->name = $name;\n\n        return $this;\n    }\n\n    /**\n     * @return string\n     */\n    public function getUrl()\n    {\n        return $this->url;\n    }\n\n    /**\n     * @param string $url\n     */\n    public function setUrl($url): self\n    {\n        $this->url = $url;\n\n        return $this;\n    }\n\n    /**\n     * @return string\n     */\n    public function getEmail()\n    {\n        return $this->email;\n    }\n\n    /**\n     * @param string $email\n     */\n    public function setEmail($email): self\n    {\n        $this->email = $email;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/ExternalDocs.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger;\n\nuse EXSyst\\Component\\Swagger\\Parts\\DescriptionPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ExtensionPart;\nuse EXSyst\\Component\\Swagger\\Parts\\UrlPart;\n\nfinal class ExternalDocs extends AbstractModel\n{\n    const REQUIRED = false;\n\n    use DescriptionPart;\n    use UrlPart;\n    use ExtensionPart;\n\n    public function __construct($data = [])\n    {\n        $this->merge($data);\n    }\n\n    protected function doMerge($data, $overwrite = false)\n    {\n        $this->mergeDescription($data, $overwrite);\n        $this->mergeExtensions($data, $overwrite);\n        $this->mergeUrl($data, $overwrite);\n    }\n\n    protected function doExport(): array\n    {\n        return [\n            'description' => $this->description,\n            'url' => $this->url,\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Header.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger;\n\nuse EXSyst\\Component\\Swagger\\Parts\\DescriptionPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ExtensionPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ItemsPart;\nuse EXSyst\\Component\\Swagger\\Parts\\TypePart;\n\nfinal class Header extends AbstractModel\n{\n    use DescriptionPart;\n    use TypePart;\n    use ItemsPart;\n    use ExtensionPart;\n\n    public function __construct($data = [])\n    {\n        $this->merge($data);\n    }\n\n    protected function doMerge($data, $overwrite = false)\n    {\n        $this->mergeDescription($data, $overwrite);\n        $this->mergeExtensions($data, $overwrite);\n        $this->mergeItems($data, $overwrite);\n        $this->mergeType($data, $overwrite);\n    }\n\n    public function doExport(): array\n    {\n        return array_merge(\n            [\n                'description' => $this->description,\n                'items' => $this->items,\n            ],\n            $this->doExportType()\n        );\n    }\n}\n"
  },
  {
    "path": "src/Info.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger;\n\nuse EXSyst\\Component\\Swagger\\Parts\\DescriptionPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ExtensionPart;\nuse EXSyst\\Component\\Swagger\\Util\\MergeHelper;\n\nfinal class Info extends AbstractModel\n{\n    const REQUIRED = false;\n\n    use DescriptionPart;\n    use ExtensionPart;\n\n    /** @var string */\n    private $title;\n\n    /** @var string */\n    private $termsOfService;\n\n    /** @var Contact */\n    private $contact;\n\n    /** @var License */\n    private $license;\n\n    /** @var string */\n    private $version;\n\n    public function __construct($data = [])\n    {\n        $this->contact = new Contact();\n        $this->license = new License();\n\n        $this->merge($data);\n    }\n\n    protected function doMerge($data, $overwrite = false)\n    {\n        MergeHelper::mergeFields($this->title, $data['title'] ?? null, $overwrite);\n        MergeHelper::mergeFields($this->termsOfService, $data['termsOfService'] ?? null, $overwrite);\n        MergeHelper::mergeFields($this->version, $data['version'] ?? null, $overwrite);\n\n        $this->contact->merge($data['contact'] ?? [], $overwrite);\n        $this->license->merge($data['license'] ?? [], $overwrite);\n\n        $this->mergeDescription($data, $overwrite);\n        $this->mergeExtensions($data, $overwrite);\n    }\n\n    protected function doExport(): array\n    {\n        return [\n            'title' => $this->title,\n            'description' => $this->description,\n            'termsOfService' => $this->termsOfService,\n            'contact' => $this->contact,\n            'license' => $this->license,\n            'version' => $this->version,\n        ];\n    }\n\n    /**\n     * @return string|null\n     */\n    public function getTitle()\n    {\n        return $this->title;\n    }\n\n    /**\n     * @param string|null $title\n     */\n    public function setTitle($title): self\n    {\n        $this->title = $title;\n\n        return $this;\n    }\n\n    /**\n     * @return string|null\n     */\n    public function getTerms()\n    {\n        return $this->termsOfService;\n    }\n\n    /**\n     * @param string|null $terms\n     */\n    public function setTerms($terms): self\n    {\n        $this->termsOfService = $terms;\n\n        return $this;\n    }\n\n    /**\n     * @return Contact\n     */\n    public function getContact()\n    {\n        return $this->contact;\n    }\n\n    /**\n     * @return License\n     */\n    public function getLicense()\n    {\n        return $this->license;\n    }\n\n    /**\n     * @return string|null\n     */\n    public function getVersion()\n    {\n        return $this->version;\n    }\n\n    /**\n     * @param string|null $version\n     *\n     * @return Info\n     */\n    public function setVersion($version): self\n    {\n        $this->version = $version;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Items.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger;\n\nfinal class Items extends Schema\n{\n    const REQUIRED = false;\n}\n"
  },
  {
    "path": "src/License.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger;\n\nuse EXSyst\\Component\\Swagger\\Parts\\ExtensionPart;\nuse EXSyst\\Component\\Swagger\\Parts\\UrlPart;\nuse EXSyst\\Component\\Swagger\\Util\\MergeHelper;\n\nfinal class License extends AbstractModel\n{\n    const REQUIRED = false;\n\n    use UrlPart;\n    use ExtensionPart;\n\n    /** @var string */\n    private $name;\n\n    public function __construct($data = [])\n    {\n        $this->merge($data);\n    }\n\n    protected function doMerge($data, $overwrite = false)\n    {\n        MergeHelper::mergeFields($this->name, $data['name'] ?? null, $overwrite);\n\n        $this->mergeExtensions($data, $overwrite);\n        $this->mergeUrl($data, $overwrite);\n    }\n\n    protected function doExport(): array\n    {\n        return [\n            'name' => $this->name,\n            'url' => $this->url,\n        ];\n    }\n\n    /**\n     * @return string\n     */\n    public function getName()\n    {\n        return $this->name;\n    }\n\n    /**\n     * @param string $name\n     */\n    public function setName($name): self\n    {\n        $this->name = $name;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Operation.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger;\n\nuse EXSyst\\Component\\Swagger\\Parts\\ConsumesPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ExtensionPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ExternalDocsPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ParametersPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ProducesPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ResponsesPart;\nuse EXSyst\\Component\\Swagger\\Parts\\SchemesPart;\nuse EXSyst\\Component\\Swagger\\Parts\\SecurityPart;\nuse EXSyst\\Component\\Swagger\\Parts\\TagsPart;\nuse EXSyst\\Component\\Swagger\\Util\\MergeHelper;\n\nfinal class Operation extends AbstractModel\n{\n    use ConsumesPart;\n    use ProducesPart;\n    use TagsPart;\n    use ParametersPart;\n    use ResponsesPart;\n    use SchemesPart;\n    use ExternalDocsPart;\n    use ExtensionPart;\n    use SecurityPart;\n\n    /** @var string */\n    private $summary;\n\n    /** @var string */\n    private $description;\n\n    /** @var string */\n    private $operationId;\n\n    /** @var bool */\n    private $deprecated;\n\n    public function __construct($data = [])\n    {\n        $this->merge($data);\n    }\n\n    protected function doMerge($data, $overwrite = false)\n    {\n        MergeHelper::mergeFields($this->summary, $data['summary'] ?? null, $overwrite);\n        MergeHelper::mergeFields($this->description, $data['description'] ?? null, $overwrite);\n        MergeHelper::mergeFields($this->operationId, $data['operationId'] ?? null, $overwrite);\n        MergeHelper::mergeFields($this->deprecated, $data['deprecated'] ?? null, $overwrite);\n\n        $this->mergeConsumes($data, $overwrite);\n        $this->mergeExtensions($data, $overwrite);\n        $this->mergeExternalDocs($data, $overwrite);\n        $this->mergeParameters($data, $overwrite);\n        $this->mergeProduces($data, $overwrite);\n        $this->mergeResponses($data, $overwrite);\n        $this->mergeSchemes($data, $overwrite);\n        $this->mergeSecurity($data, $overwrite);\n        $this->mergeTags($data, $overwrite);\n    }\n\n    protected function doExport(): array\n    {\n        return [\n            'summary' => $this->getSummary(),\n            'description' => $this->getDescription(),\n            'operationId' => $this->getOperationId(),\n            'deprecated' => $this->getDeprecated(),\n            'consumes' => $this->getConsumes() ?: null,\n            'produces' => $this->getProduces() ?: null,\n            'parameters' => $this->getParameters(),\n            'responses' => $this->getResponses(),\n            'schemes' => $this->getSchemes() ?: null,\n            'tags' => $this->getTags() ?: null,\n            'externalDocs' => $this->getExternalDocs(),\n            'security' => $this->getSecurity(),\n        ];\n    }\n\n    /**\n     * @return string\n     */\n    public function getSummary()\n    {\n        return $this->summary;\n    }\n\n    /**\n     * @param string $summary\n     */\n    public function setSummary($summary): self\n    {\n        $this->summary = $summary;\n\n        return $this;\n    }\n\n    /**\n     * @return string\n     */\n    public function getDescription()\n    {\n        return $this->description;\n    }\n\n    /**\n     * @param string $description\n     */\n    public function setDescription($description): self\n    {\n        $this->description = $description;\n\n        return $this;\n    }\n\n    /**\n     * @return string\n     */\n    public function getOperationId()\n    {\n        return $this->operationId;\n    }\n\n    /**\n     * @param string $operationId\n     */\n    public function setOperationId($operationId): self\n    {\n        $this->operationId = $operationId;\n\n        return $this;\n    }\n\n    /**\n     * @return bool\n     */\n    public function getDeprecated()\n    {\n        return $this->deprecated;\n    }\n\n    /**\n     * @param bool $deprecated\n     */\n    public function setDeprecated($deprecated): self\n    {\n        $this->deprecated = $deprecated;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Parameter.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger;\n\nuse EXSyst\\Component\\Swagger\\Parts\\DescriptionPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ExtensionPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ItemsPart;\nuse EXSyst\\Component\\Swagger\\Parts\\RefPart;\nuse EXSyst\\Component\\Swagger\\Parts\\RequiredPart;\nuse EXSyst\\Component\\Swagger\\Parts\\SchemaPart;\nuse EXSyst\\Component\\Swagger\\Parts\\TypePart;\nuse EXSyst\\Component\\Swagger\\Util\\MergeHelper;\n\nfinal class Parameter extends AbstractModel\n{\n    use RefPart;\n    use DescriptionPart;\n    use SchemaPart;\n    use TypePart;\n    use ItemsPart;\n    use RequiredPart;\n    use ExtensionPart;\n\n    /** @var string */\n    private $name;\n\n    /** @var string */\n    private $in;\n\n    /** @var bool|null */\n    private $allowEmptyValue;\n\n    public function __construct($data = [])\n    {\n        $data = $this->normalize($data);\n        $this->merge($data);\n\n        if (!$this->hasRef()) {\n            if (!isset($data['name']) || !isset($data['in'])) {\n                throw new \\InvalidArgumentException('\"in\" and \"name\" are required for parameters');\n            }\n\n            $this->name = $data['name'];\n            $this->in = $data['in'];\n        }\n    }\n\n    protected function doMerge($data, $overwrite = false)\n    {\n        MergeHelper::mergeFields($this->allowEmptyValue, $data['allowEmptyValue'] ?? null, $overwrite);\n\n        $this->mergeDescription($data, $overwrite);\n        $this->mergeExtensions($data, $overwrite);\n        $this->mergeItems($data, $overwrite);\n        $this->mergeRef($data, $overwrite);\n        $this->mergeRequired($data, $overwrite);\n        $this->mergeSchema($data, $overwrite);\n        $this->mergeType($data, $overwrite);\n    }\n\n    protected function doExport(): array\n    {\n        if ($this->hasRef()) {\n            return ['$ref' => $this->getRef()];\n        }\n\n        return array_merge(\n            [\n                'name' => $this->name,\n                'in' => $this->in,\n                'allowEmptyValue' => $this->allowEmptyValue,\n                'required' => $this->required,\n                'description' => $this->description,\n                'schema' => $this->schema,\n                'items' => $this->items,\n            ],\n            $this->doExportType()\n        );\n    }\n\n    /**\n     * @return string\n     */\n    public function getName()\n    {\n        return $this->name;\n    }\n\n    /**\n     * @return string\n     */\n    public function getIn()\n    {\n        return $this->in;\n    }\n\n    /**\n     * @return bool\n     */\n    public function getAllowEmptyValue()\n    {\n        return $this->allowEmptyValue;\n    }\n\n    /**\n     * Sets the ability to pass empty-valued parameters. This is valid only for either `query` or\n     * `formData` parameters and allows you to send a parameter with a name only or an empty value.\n     * Default value is `false`.\n     *\n     * @param bool $allowEmptyValue\n     */\n    public function setAllowEmptyValue($allowEmptyValue): self\n    {\n        $this->allowEmptyValue = $allowEmptyValue;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Parts/ConsumesPart.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Parts;\n\nuse EXSyst\\Component\\Swagger\\Util\\MergeHelper;\n\n/**\n * @internal\n */\ntrait ConsumesPart\n{\n    private $consumes;\n\n    private function mergeConsumes(array $data, bool $overwrite)\n    {\n        MergeHelper::mergeFields($this->consumes, $data['consumes'] ?? null, $overwrite);\n    }\n\n    /**\n     * Return consumes.\n     */\n    public function getConsumes()\n    {\n        return $this->consumes;\n    }\n}\n"
  },
  {
    "path": "src/Parts/DescriptionPart.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Parts;\n\nuse EXSyst\\Component\\Swagger\\Util\\MergeHelper;\n\n/**\n * @internal\n */\ntrait DescriptionPart\n{\n    /** @var string|null */\n    private $description;\n\n    private function mergeDescription(array $data, bool $overwrite)\n    {\n        MergeHelper::mergeFields($this->description, $data['description'] ?? null, $overwrite);\n    }\n\n    /**\n     * @return string|null\n     */\n    public function getDescription()\n    {\n        return $this->description;\n    }\n\n    /**\n     * @param string $description\n     *\n     * @return $this\n     */\n    public function setDescription(string $description = null): self\n    {\n        $this->description = $description;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Parts/ExtensionPart.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Parts;\n\n/**\n * @internal\n */\ntrait ExtensionPart\n{\n    private $extensions = [];\n\n    private function mergeExtensions(array $data, bool $overwrite)\n    {\n        foreach ($data as $name => $value) {\n            if (0 === strpos($name, 'x-')) {\n                $this->extensions[substr($name, 2)] = $value;\n            }\n        }\n    }\n\n    /**\n     * Returns extensions.\n     *\n     * @return array\n     */\n    public function getExtensions(): array\n    {\n        return $this->extensions;\n    }\n}\n"
  },
  {
    "path": "src/Parts/ExternalDocsPart.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Parts;\n\nuse EXSyst\\Component\\Swagger\\ExternalDocs;\n\n/**\n * @internal\n */\ntrait ExternalDocsPart\n{\n    /** @var ExternalDocs|null */\n    private $externalDocs;\n\n    private function mergeExternalDocs(array $data, bool $overwrite)\n    {\n        if (isset($data['externalDocs'])) {\n            $this->getExternalDocs()->merge($data['externalDocs']);\n        }\n    }\n\n    /**\n     * @return ExternalDocs\n     */\n    public function getExternalDocs(): ExternalDocs\n    {\n        if (null === $this->externalDocs) {\n            $this->externalDocs = new ExternalDocs();\n        }\n\n        return $this->externalDocs;\n    }\n\n    public function setExternalDocs(ExternalDocs $externalDocs): self\n    {\n        $this->externalDocs = $externalDocs;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Parts/ItemsPart.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Parts;\n\nuse EXSyst\\Component\\Swagger\\Items;\n\n/**\n * @internal\n */\ntrait ItemsPart\n{\n    /** @var Items|null */\n    private $items;\n\n    private function mergeItems(array $data, bool $overwrite)\n    {\n        if (isset($data['items'])) {\n            $this->getItems()->merge($data['items'], $overwrite);\n        }\n    }\n\n    /**\n     * Returns the items.\n     */\n    public function getItems(): Items\n    {\n        if (null === $this->items) {\n            $this->items = new Items();\n        }\n\n        return $this->items;\n    }\n}\n"
  },
  {
    "path": "src/Parts/ParametersPart.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Parts;\n\nuse EXSyst\\Component\\Swagger\\Collections\\Parameters;\n\n/**\n * @internal\n */\ntrait ParametersPart\n{\n    /** @var Parameters|null */\n    private $parameters;\n\n    private function mergeParameters(array $data, bool $overwrite)\n    {\n        if (isset($data['parameters'])) {\n            $this->getParameters()->merge($data['parameters'], $overwrite);\n        }\n    }\n\n    /**\n     * Return parameters.\n     */\n    public function getParameters(): Parameters\n    {\n        if (null === $this->parameters) {\n            $this->parameters = new Parameters();\n        }\n\n        return $this->parameters;\n    }\n}\n"
  },
  {
    "path": "src/Parts/ProducesPart.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Parts;\n\n/**\n * @internal\n */\ntrait ProducesPart\n{\n    private $produces = [];\n\n    private function mergeProduces(array $data, bool $overwrite)\n    {\n        foreach ($data['produces'] ?? [] as $produce) {\n            $this->produces[$produce] = true;\n        }\n    }\n\n    /**\n     * Return produces.\n     */\n    public function getProduces(): array\n    {\n        return array_keys($this->produces);\n    }\n}\n"
  },
  {
    "path": "src/Parts/RefPart.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Parts;\n\n/**\n * @internal\n */\ntrait RefPart\n{\n    /** @var string|null */\n    private $ref;\n\n    private function mergeRef(array $data, bool $overwrite)\n    {\n        $this->ref = $data['$ref'] ?? null;\n    }\n\n    /**\n     * @return string|null\n     */\n    public function getRef()\n    {\n        return $this->ref;\n    }\n\n    /**\n     * @param string|null $ref\n     */\n    public function setRef(string $ref = null): self\n    {\n        $this->ref = $ref;\n\n        return $this;\n    }\n\n    public function hasRef(): bool\n    {\n        return null !== $this->ref;\n    }\n}\n"
  },
  {
    "path": "src/Parts/RequiredPart.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Parts;\n\nuse EXSyst\\Component\\Swagger\\Util\\MergeHelper;\n\n/**\n * @internal\n */\ntrait RequiredPart\n{\n    /** @var bool|null */\n    private $required;\n\n    private function mergeRequired(array $data, bool $overwrite)\n    {\n        MergeHelper::mergeFields($this->required, $data['required'] ?? null, $overwrite);\n    }\n\n    /**\n     * @return bool|null\n     */\n    public function getRequired()\n    {\n        return $this->required;\n    }\n\n    /**\n     * @param bool|null $required\n     */\n    public function setRequired(bool $required = null): self\n    {\n        $this->required = $required;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Parts/ResponsesPart.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Parts;\n\nuse EXSyst\\Component\\Swagger\\Collections\\Responses;\n\n/**\n * @internal\n */\ntrait ResponsesPart\n{\n    /** @var Responses|null */\n    private $responses;\n\n    private function mergeResponses(array $data, bool $overwrite)\n    {\n        if (isset($data['responses'])) {\n            $this->getResponses()->merge($data['responses'], $overwrite);\n        }\n    }\n\n    /**\n     * Return responses.\n     */\n    public function getResponses(): Responses\n    {\n        if (null === $this->responses) {\n            $this->responses = new Responses();\n        }\n\n        return $this->responses;\n    }\n}\n"
  },
  {
    "path": "src/Parts/SchemaPart.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Parts;\n\nuse EXSyst\\Component\\Swagger\\Schema;\n\n/**\n * @internal\n */\ntrait SchemaPart\n{\n    /** @var Schema|null */\n    private $schema;\n\n    private function mergeSchema(array $data, bool $overwrite)\n    {\n        if (isset($data['schema'])) {\n            $this->getSchema()->merge($data['schema'], $overwrite);\n        }\n    }\n\n    public function getSchema(): Schema\n    {\n        if (null === $this->schema) {\n            $this->schema = new Schema();\n        }\n\n        return $this->schema ?: new Schema();\n    }\n}\n"
  },
  {
    "path": "src/Parts/SchemesPart.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Parts;\n\n/**\n * @internal\n */\ntrait SchemesPart\n{\n    private $schemes = [];\n\n    private function mergeSchemes(array $data, bool $overwrite)\n    {\n        foreach ($data['schemes'] ?? [] as $scheme) {\n            $this->schemes[$scheme] = true;\n        }\n    }\n\n    /**\n     * Return schemes.\n     */\n    public function getSchemes(): array\n    {\n        return array_keys($this->schemes);\n    }\n}\n"
  },
  {
    "path": "src/Parts/SecurityPart.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Parts;\n\nuse EXSyst\\Component\\Swagger\\Util\\MergeHelper;\n\n/**\n * @internal\n */\ntrait SecurityPart\n{\n    /** @var array */\n    private $security;\n\n    private function mergeSecurity(array $data, bool $overwrite)\n    {\n        MergeHelper::mergeFields($this->security, $data['security'] ?? null, $overwrite);\n    }\n\n    /**\n     * @return array|null\n     */\n    public function getSecurity()\n    {\n        return $this->security;\n    }\n\n    public function setSecurity(array $security = null): self\n    {\n        $this->security = $security;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Parts/TagsPart.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Parts;\n\nuse EXSyst\\Component\\Swagger\\Tag;\n\n/**\n * @internal\n */\ntrait TagsPart\n{\n    private $tags = [];\n\n    private function mergeTags(array $data, bool $overwrite)\n    {\n        foreach ($data['tags'] ?? [] as $value) {\n            $tag = new Tag($value);\n            $this->tags[$tag->getName()] = $tag;\n        }\n    }\n\n    /**\n     * Return tags.\n     */\n    public function getTags(): array\n    {\n        return array_values($this->tags);\n    }\n\n    protected function exportTags(): array\n    {\n        $out = [];\n        foreach ($this->tags as $tag) {\n            $out[] = $tag->toArray();\n        }\n\n        return $out;\n    }\n}\n"
  },
  {
    "path": "src/Parts/TypePart.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Parts;\n\nuse EXSyst\\Component\\Swagger\\Util\\MergeHelper;\n\n/**\n * @internal\n */\ntrait TypePart\n{\n    /** @var string */\n    private $type;\n\n    /** @var string */\n    private $format;\n\n    /** @var string */\n    private $collectionFormat;\n\n    /** @var mixed */\n    private $default;\n\n    /** @var float */\n    private $maximum;\n\n    /** @var bool */\n    private $exclusiveMaximum;\n\n    /** @var float */\n    private $minimum;\n\n    /** @var bool */\n    private $exclusiveMinimum;\n\n    /** @var int */\n    private $maxLength;\n\n    /** @var int */\n    private $minLength;\n\n    /** @var string */\n    private $pattern;\n\n    /** @var int */\n    private $maxItems;\n\n    /** @var int */\n    private $minItems;\n\n    /** @var bool */\n    private $uniqueItems;\n\n    /** @var mixed */\n    private $enum;\n\n    /** @var float */\n    private $multipleOf;\n\n    private function mergeType(array $data, bool $overwrite)\n    {\n        foreach ($this->getTypeFields() as $field) {\n            MergeHelper::mergeFields($this->{$field}, $data[$field] ?? null, $overwrite);\n        }\n    }\n\n    protected function doExportType(): array\n    {\n        $return = [];\n        foreach ($this->getTypeFields() as $field) {\n            $return[$field] = $this->{$field};\n        }\n\n        return $return;\n    }\n\n    private function getTypeFields(): array\n    {\n        return [\n            'type',\n            'format',\n            'collectionFormat',\n            'default',\n            'maximum',\n            'exclusiveMaximum',\n            'minimum',\n            'exclusiveMinimum',\n            'maxLength',\n            'minLength',\n            'pattern',\n            'maxItems',\n            'minItems',\n            'uniqueItems',\n            'enum',\n            'multipleOf',\n        ];\n    }\n\n    /**\n     * @return string|null\n     */\n    public function getType()\n    {\n        return $this->type;\n    }\n\n    /**\n     * @param string|null $type\n     */\n    public function setType($type): self\n    {\n        $this->type = $type;\n\n        return $this;\n    }\n\n    /**\n     * @return string|null\n     */\n    public function getFormat()\n    {\n        return $this->format;\n    }\n\n    /**\n     * Sets the extending format for the type.\n     *\n     * @param string|null $format\n     */\n    public function setFormat($format): self\n    {\n        $this->format = $format;\n\n        return $this;\n    }\n\n    /**\n     * @return string|null\n     */\n    public function getCollectionFormat()\n    {\n        return $this->collectionFormat;\n    }\n\n    /**\n     * Determines the format of the array if type array is used. Possible values are:.\n     *\n     * - `csv` - comma separated values `foo,bar`.\n     * - `ssv` - space separated values `foo bar`.\n     * - `tsv` - tab separated values `foo\\tbar`.\n     * - `pipes` - pipe separated values `foo|bar`.\n     * - `multi` - corresponds to multiple parameter instances instead of multiple values for a\n     * single instance `foo=bar&foo=baz`. This is valid only for parameters in \"query\" or \"formData\".\n     *\n     * Default value is `csv`.\n     *\n     *\n     * @param string|null $collectionFormat\n     */\n    public function setCollectionFormat($collectionFormat): self\n    {\n        $this->collectionFormat = $collectionFormat;\n\n        return $this;\n    }\n\n    /**\n     * @return mixed\n     */\n    public function getDefault()\n    {\n        return $this->default;\n    }\n\n    /**\n     * @param mixed|null $default\n     */\n    public function setDefault($default): self\n    {\n        $this->default = $default;\n\n        return $this;\n    }\n\n    /**\n     * @return float|null\n     */\n    public function getMaximum()\n    {\n        return $this->maximum;\n    }\n\n    /**\n     * @param float|null $maximum\n     */\n    public function setMaximum($maximum): self\n    {\n        $this->maximum = $maximum;\n\n        return $this;\n    }\n\n    /**\n     * @return bool|null\n     */\n    public function isExclusiveMaximum()\n    {\n        return $this->exclusiveMaximum;\n    }\n\n    /**\n     * @param bool|null $exclusiveMaximum\n     */\n    public function setExclusiveMaximum($exclusiveMaximum): self\n    {\n        $this->exclusiveMaximum = $exclusiveMaximum;\n\n        return $this;\n    }\n\n    /**\n     * @return float|null\n     */\n    public function getMinimum()\n    {\n        return $this->minimum;\n    }\n\n    /**\n     * @param float|null $minimum\n     */\n    public function setMinimum($minimum): self\n    {\n        $this->minimum = $minimum;\n\n        return $this;\n    }\n\n    /**\n     * @return bool|null\n     */\n    public function isExclusiveMinimum()\n    {\n        return $this->exclusiveMinimum;\n    }\n\n    /**\n     * @param bool|null $exclusiveMinimum\n     *\n     * @return $this\n     */\n    public function setExclusiveMinimum($exclusiveMinimum)\n    {\n        $this->exclusiveMinimum = $exclusiveMinimum;\n\n        return $this;\n    }\n\n    /**\n     * @return int|null\n     */\n    public function getMaxLength()\n    {\n        return $this->maxLength;\n    }\n\n    /**\n     * @param int|null $maxLength\n     */\n    public function setMaxLength($maxLength): self\n    {\n        $this->maxLength = $maxLength;\n\n        return $this;\n    }\n\n    /**\n     * @return int|null\n     */\n    public function getMinLength()\n    {\n        return $this->minLength;\n    }\n\n    /**\n     * @param int|null $minLength\n     */\n    public function setMinLength($minLength): self\n    {\n        $this->minLength = $minLength;\n\n        return $this;\n    }\n\n    /**\n     * @return string|null\n     */\n    public function getPattern()\n    {\n        return $this->pattern;\n    }\n\n    /**\n     * @param string|null $pattern\n     */\n    public function setPattern($pattern): self\n    {\n        $this->pattern = $pattern;\n\n        return $this;\n    }\n\n    /**\n     * @return int|null\n     */\n    public function getMaxItems()\n    {\n        return $this->maxItems;\n    }\n\n    /**\n     * @param int|null $maxItems\n     */\n    public function setMaxItems($maxItems): self\n    {\n        $this->maxItems = $maxItems;\n\n        return $this;\n    }\n\n    /**\n     * @return int|null\n     */\n    public function getMinItems()\n    {\n        return $this->minItems;\n    }\n\n    /**\n     * @param int|null $minItems\n     */\n    public function setMinItems($minItems): self\n    {\n        $this->minItems = $minItems;\n\n        return $this;\n    }\n\n    /**\n     * @return bool|null\n     */\n    public function hasUniqueItems()\n    {\n        return $this->uniqueItems;\n    }\n\n    /**\n     * @param bool|null $uniqueItems\n     */\n    public function setUniqueItems($uniqueItems): self\n    {\n        $this->uniqueItems = $uniqueItems;\n\n        return $this;\n    }\n\n    /**\n     * @return mixed\n     */\n    public function getEnum()\n    {\n        return $this->enum;\n    }\n\n    /**\n     * @param mixed $enum\n     */\n    public function setEnum($enum): self\n    {\n        $this->enum = $enum;\n\n        return $this;\n    }\n\n    /**\n     * @return float|null\n     */\n    public function getMultipleOf()\n    {\n        return $this->multipleOf;\n    }\n\n    /**\n     * @param float|null $multipleOf\n     */\n    public function setMultipleOf($multipleOf): self\n    {\n        $this->multipleOf = $multipleOf;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Parts/UrlPart.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Parts;\n\nuse EXSyst\\Component\\Swagger\\Util\\MergeHelper;\n\n/**\n * @internal\n */\ntrait UrlPart\n{\n    /** @var string|null */\n    private $url;\n\n    private function mergeUrl(array $data, bool $overwrite)\n    {\n        MergeHelper::mergeFields($this->url, $data['url'] ?? null, $overwrite);\n    }\n\n    /**\n     * @return string|null\n     */\n    public function getUrl()\n    {\n        return $this->url;\n    }\n\n    /**\n     * @param string $url\n     */\n    public function setUrl(string $url = null): self\n    {\n        $this->url = $url;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Path.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger;\n\nuse EXSyst\\Component\\Swagger\\Parts\\ExtensionPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ParametersPart;\n\nfinal class Path extends AbstractModel\n{\n    use ExtensionPart;\n    use ParametersPart;\n\n    private $operations = [];\n\n    public function __construct($data = [])\n    {\n        $this->merge($data);\n    }\n\n    protected function doMerge($data, $overwrite = false)\n    {\n        foreach (Swagger::$METHODS as $method) {\n            if (isset($data[$method])) {\n                $this->getOperation($method)->merge($data[$method]);\n            }\n        }\n        $this->mergeExtensions($data, $overwrite);\n        $this->mergeParameters($data, $overwrite);\n    }\n\n    protected function doExport(): array\n    {\n        return array_merge($this->operations, array('parameters' => $this->getParameters()));\n    }\n\n    public function getOperations(): array\n    {\n        return $this->operations;\n    }\n\n    /**\n     * Gets the operation for the given method, creates one if none exists.\n     */\n    public function getOperation(string $method): Operation\n    {\n        if (!$this->hasOperation($method)) {\n            $this->setOperation($method, new Operation());\n        }\n\n        return $this->operations[$method];\n    }\n\n    /**\n     * Sets the operation for a method.\n     */\n    public function setOperation(string $method, Operation $operation): self\n    {\n        $this->operations[$method] = $operation;\n\n        return $this;\n    }\n\n    public function hasOperation(string $method): bool\n    {\n        return isset($this->operations[$method]);\n    }\n\n    /**\n     * Removes an operation for the given method.\n     */\n    public function removeOperation(string $method): self\n    {\n        unset($this->operations[$method]);\n\n        return $this;\n    }\n\n    /**\n     * Returns all methods for this path.\n     */\n    public function getMethods(): array\n    {\n        return array_keys($this->operations);\n    }\n}\n"
  },
  {
    "path": "src/Response.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger;\n\nuse EXSyst\\Component\\Swagger\\Collections\\Headers;\nuse EXSyst\\Component\\Swagger\\Parts\\DescriptionPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ExtensionPart;\nuse EXSyst\\Component\\Swagger\\Parts\\RefPart;\nuse EXSyst\\Component\\Swagger\\Parts\\SchemaPart;\nuse EXSyst\\Component\\Swagger\\Util\\MergeHelper;\n\nfinal class Response extends AbstractModel\n{\n    use RefPart;\n    use DescriptionPart;\n    use SchemaPart;\n    use ExtensionPart;\n\n    private $examples = [];\n\n    /** @var Headers */\n    private $headers;\n\n    public function __construct($data = [])\n    {\n        $this->headers = new Headers();\n\n        $this->merge($data);\n    }\n\n    protected function doMerge($data, $overwrite = false)\n    {\n        foreach ($data['examples'] ?? [] as $mimeType => $example) {\n            $this->examples[$mimeType] = $this->examples[$mimeType] ?? null;\n            MergeHelper::mergeFields($this->examples[$mimeType], $example, $overwrite);\n        }\n\n        $this->headers->merge($data['headers'] ?? [], $overwrite);\n\n        $this->mergeDescription($data, $overwrite);\n        $this->mergeExtensions($data, $overwrite);\n        $this->mergeRef($data, $overwrite);\n        $this->mergeSchema($data, $overwrite);\n    }\n\n    protected function doExport(): array\n    {\n        if ($this->hasRef()) {\n            return ['$ref' => $this->getRef()];\n        }\n\n        return [\n            'description' => $this->description,\n            'schema' => $this->schema,\n            'headers' => $this->headers,\n            'examples' => $this->examples ?: null,\n        ];\n    }\n\n    public function getExamples(): array\n    {\n        return $this->examples;\n    }\n\n    /**\n     * Returns headers for this response.\n     */\n    public function getHeaders(): Headers\n    {\n        return $this->headers;\n    }\n}\n"
  },
  {
    "path": "src/Schema.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger;\n\nuse EXSyst\\Component\\Swagger\\Collections\\Definitions;\nuse EXSyst\\Component\\Swagger\\Parts\\DescriptionPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ExtensionPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ExternalDocsPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ItemsPart;\nuse EXSyst\\Component\\Swagger\\Parts\\RefPart;\nuse EXSyst\\Component\\Swagger\\Parts\\TypePart;\nuse EXSyst\\Component\\Swagger\\Util\\MergeHelper;\n\nclass Schema extends AbstractModel\n{\n    use RefPart;\n    use TypePart;\n    use DescriptionPart;\n    use ItemsPart;\n    use ExternalDocsPart;\n    use ExtensionPart;\n\n    /** @var string */\n    private $discriminator;\n\n    /** @var bool */\n    private $readOnly;\n\n    /** @var string */\n    private $title;\n\n    /** @var string */\n    private $example;\n\n    /** @var array|bool */\n    private $required;\n\n    /** @var Definitions */\n    private $properties;\n\n    /** @var array */\n    private $allOf = [];\n\n    /** @var Schema */\n    private $additionalProperties;\n\n    public function __construct($data = [])\n    {\n        $this->properties = new Definitions();\n        $this->merge($data);\n    }\n\n    protected function doMerge($data, $overwrite = false)\n    {\n        MergeHelper::mergeFields($this->required, $data['required'] ?? null, $overwrite);\n        MergeHelper::mergeFields($this->title, $data['title'] ?? null, $overwrite);\n        MergeHelper::mergeFields($this->discriminator, $data['discriminator'] ?? null, $overwrite);\n        MergeHelper::mergeFields($this->readOnly, $data['readOnly'] ?? null, $overwrite);\n        MergeHelper::mergeFields($this->example, $data['example'] ?? null, $overwrite);\n\n        $this->properties->merge($data['properties'] ?? [], $overwrite);\n\n        foreach ($data['allOf'] ?? [] as $schema) {\n            $this->allOf[] = new self($schema);\n        }\n\n        if (isset($data['additionalProperties'])) {\n            if (null === $this->additionalProperties) {\n                $this->additionalProperties = new self();\n            }\n\n            if (true === $data['additionalProperties']) {\n                $data['additionalProperties'] = [];\n            }\n\n            $this->additionalProperties->merge($data['additionalProperties'], $overwrite);\n        }\n\n        $this->mergeDescription($data, $overwrite);\n        $this->mergeExternalDocs($data, $overwrite);\n        $this->mergeExtensions($data, $overwrite);\n        $this->mergeItems($data, $overwrite);\n        $this->mergeRef($data, $overwrite);\n        $this->mergeType($data, $overwrite);\n    }\n\n    protected function doExport()\n    {\n        if ($this->hasRef()) {\n            return ['$ref' => $this->getRef()];\n        }\n\n        // if \"additionalProperties\" has no special types/refs, it must return `{}` or `true`\n        // @see https://swagger.io/docs/specification/data-models/dictionaries/\n        $additionalProperties = ($this->additionalProperties instanceof self && [] === $this->additionalProperties->toArray()) ?: $this->additionalProperties;\n\n        return array_merge([\n            'title' => $this->title,\n            'discriminator' => $this->discriminator,\n            'description' => $this->description,\n            'readOnly' => $this->readOnly,\n            'example' => $this->example,\n            'externalDocs' => $this->externalDocs,\n            'items' => $this->items,\n            'required' => $this->required,\n            'properties' => $this->properties,\n            'additionalProperties' => $additionalProperties,\n            'allOf' => $this->allOf ?: null,\n        ], $this->doExportType());\n    }\n\n    /**\n     * @return bool|array\n     */\n    public function getRequired()\n    {\n        return $this->required;\n    }\n\n    /**\n     * @param bool|array $required\n     *\n     * @return $this\n     */\n    public function setRequired($required)\n    {\n        $this->required = $required;\n\n        return $this;\n    }\n\n    /**\n     * @return string|null\n     */\n    public function getDiscriminator()\n    {\n        return $this->discriminator;\n    }\n\n    /**\n     * @param string|null $discriminator\n     *\n     * @return Schema\n     */\n    public function setDiscriminator($discriminator)\n    {\n        $this->discriminator = $discriminator;\n\n        return $this;\n    }\n\n    /**\n     * @return bool|null\n     */\n    public function isReadOnly()\n    {\n        return $this->readOnly;\n    }\n\n    /**\n     * @param bool|null $readOnly\n     *\n     * @return Schema\n     */\n    public function setReadOnly($readOnly)\n    {\n        $this->readOnly = $readOnly;\n\n        return $this;\n    }\n\n    /**\n     * @return string|null\n     */\n    public function getExample()\n    {\n        return $this->example;\n    }\n\n    /**\n     * @param string|null $example\n     *\n     * @return Schema\n     */\n    public function setExample($example)\n    {\n        $this->example = $example;\n\n        return $this;\n    }\n\n    /**\n     * @return string|null\n     */\n    public function getTitle()\n    {\n        return $this->title;\n    }\n\n    /**\n     * @param string|null $title\n     *\n     * @return $this\n     */\n    public function setTitle($title)\n    {\n        $this->title = $title;\n\n        return $this;\n    }\n\n    /**\n     * @return Definitions\n     */\n    public function getProperties()\n    {\n        return $this->properties;\n    }\n\n    /**\n     * @return array\n     */\n    public function getAllOf(): array\n    {\n        return $this->allOf;\n    }\n\n    /**\n     * @return Schema|null\n     */\n    public function getAdditionalProperties()\n    {\n        return $this->additionalProperties;\n    }\n}\n"
  },
  {
    "path": "src/SecurityScheme.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger;\n\nuse EXSyst\\Component\\Swagger\\Parts\\DescriptionPart;\nuse EXSyst\\Component\\Swagger\\Util\\MergeHelper;\n\nclass SecurityScheme extends AbstractModel\n{\n    use DescriptionPart;\n\n    /** @var string */\n    private $name;\n\n    /** @var string */\n    private $type;\n\n    /** @var string */\n    private $in;\n\n    /** @var string */\n    private $flow;\n\n    /** @var string */\n    private $authorizationUrl;\n\n    /** @var string */\n    private $tokenUrl;\n\n    /** @var array */\n    private $scopes;\n\n    public function __construct($data = [])\n    {\n        $this->merge($data);\n    }\n\n    /**\n     * Return the name of the header or query parameter to be used.\n     *\n     * @return string\n     */\n    public function getName()\n    {\n        return $this->name;\n    }\n\n    /**\n     * Sets the name of the header or query parameter to be used.\n     *\n     * @param string $name\n     *\n     * @return $this\n     */\n    public function setName($name)\n    {\n        $this->name = $name;\n\n        return $this;\n    }\n\n    /**\n     * Returns the type of the security scheme.\n     *\n     * @return string\n     */\n    public function getType()\n    {\n        return $this->type;\n    }\n\n    /**\n     * Sets the type of the security scheme.\n     *\n     * @param string $type Valid values are \"basic\", \"apiKey\" or \"oauth2\"\n     *\n     * @return $this\n     */\n    public function setType($type)\n    {\n        $this->type = $type;\n\n        return $this;\n    }\n\n    /**\n     * Returns the location of the API key.\n     *\n     * @return string\n     */\n    public function getIn()\n    {\n        return $this->in;\n    }\n\n    /**\n     * Sets the location of the API key.\n     *\n     * @param string $in Valid values are \"query\" or \"header\"\n     *\n     * @return $this\n     */\n    public function setIn($in)\n    {\n        $this->in = $in;\n\n        return $this;\n    }\n\n    /**\n     * Retunrs the flow used by the OAuth2 security scheme.\n     *\n     * @return string\n     */\n    public function getFlow()\n    {\n        return $this->flow;\n    }\n\n    /**\n     * Sets the flow used by the OAuth2 security scheme.\n     *\n     * @param string $flow Valid values are \"implicit\", \"password\", \"application\" or \"accessCode\"\n     *\n     * @return $this\n     */\n    public function setFlow($flow)\n    {\n        $this->flow = $flow;\n\n        return $this;\n    }\n\n    /**\n     * Returns the authorization URL to be used for this flow.\n     *\n     * @return string\n     */\n    public function getAuthorizationUrl()\n    {\n        return $this->authorizationUrl;\n    }\n\n    /**\n     * Sets the authorization URL to be used for this flow.\n     *\n     * @param string $authorizationUrl\n     *\n     * @return $this\n     */\n    public function setAuthorizationUrl($authorizationUrl)\n    {\n        $this->authorizationUrl = $authorizationUrl;\n\n        return $this;\n    }\n\n    /**\n     * Returns the token URL to be used for this flow.\n     *\n     * @return string\n     */\n    public function getTokenUrl()\n    {\n        return $this->tokenUrl;\n    }\n\n    /**\n     * Sets the token URL to be used for this flow.\n     *\n     * @param string $tokenUrl\n     *\n     * @return $this\n     */\n    public function setTokenUrl($tokenUrl)\n    {\n        $this->tokenUrl = $tokenUrl;\n\n        return $this;\n    }\n\n    /**\n     * Returns the scopes.\n     *\n     * @return array\n     */\n    public function getScopes()\n    {\n        return $this->scopes;\n    }\n\n    /**\n     * @return $this\n     */\n    public function setScopes(array $scopes = null)\n    {\n        $this->scopes = $scopes;\n\n        return $this;\n    }\n\n    protected function doMerge($data, $overwrite = false)\n    {\n        MergeHelper::mergeFields($this->name, $data['name'] ?? null, $overwrite);\n        MergeHelper::mergeFields($this->type, $data['type'] ?? null, $overwrite);\n        MergeHelper::mergeFields($this->in, $data['in'] ?? null, $overwrite);\n        MergeHelper::mergeFields($this->flow, $data['flow'] ?? null, $overwrite);\n        MergeHelper::mergeFields($this->authorizationUrl, $data['authorizationUrl'] ?? null, $overwrite);\n        MergeHelper::mergeFields($this->tokenUrl, $data['tokenUrl'] ?? null, $overwrite);\n        MergeHelper::mergeFields($this->scopes, $data['scopes'] ?? null, $overwrite);\n\n        $this->mergeDescription($data, $overwrite);\n    }\n\n    protected function doExport()\n    {\n        return [\n            'name' => $this->name,\n            'type' => $this->type,\n            'in' => $this->in,\n            'flow' => $this->flow,\n            'authorizationUrl' => $this->authorizationUrl,\n            'tokenUrl' => $this->tokenUrl,\n            'scopes' => $this->scopes,\n            'description' => $this->description,\n        ];\n    }\n}\n"
  },
  {
    "path": "src/Swagger.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger;\n\nuse EXSyst\\Component\\Swagger\\Collections\\Definitions;\nuse EXSyst\\Component\\Swagger\\Collections\\Paths;\nuse EXSyst\\Component\\Swagger\\Parts\\ConsumesPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ExtensionPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ExternalDocsPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ProducesPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ResponsesPart;\nuse EXSyst\\Component\\Swagger\\Parts\\SchemesPart;\nuse EXSyst\\Component\\Swagger\\Parts\\SecurityPart;\nuse EXSyst\\Component\\Swagger\\Parts\\TagsPart;\nuse EXSyst\\Component\\Swagger\\Util\\MergeHelper;\n\nfinal class Swagger extends AbstractModel\n{\n    use SchemesPart;\n    use ConsumesPart;\n    use ProducesPart;\n    use TagsPart;\n    use ResponsesPart;\n    use ExternalDocsPart;\n    use ExtensionPart;\n    use SecurityPart;\n\n    public static $METHODS = ['get', 'post', 'put', 'patch', 'delete', 'options', 'head'];\n\n    /** @var Info */\n    private $info;\n\n    /** @var string */\n    private $host;\n\n    /** @var string */\n    private $basePath;\n\n    /** @var Paths */\n    private $paths;\n\n    /** @var Definitions */\n    private $definitions;\n\n    /** @var array */\n    private $parameters;\n\n    /** @var array */\n    private $securityDefinitions = [];\n\n    /**\n     * @param string $filename\n     *\n     * @return static\n     */\n    public static function fromFile(string $filename): self\n    {\n        return new static(json_decode(file_get_contents($filename), true));\n    }\n\n    public function __construct($data = [])\n    {\n        $this->info = new Info();\n        $this->definitions = new Definitions();\n        $this->paths = new Paths();\n\n        $this->merge($data);\n    }\n\n    protected function doMerge($data, $overwrite = false)\n    {\n        MergeHelper::mergeFields($this->host, $data['host'] ?? null, $overwrite);\n        MergeHelper::mergeFields($this->basePath, $data['basePath'] ?? null, $overwrite);\n\n        if (isset($data['info'])) {\n            $this->info->merge($data['info'], $overwrite);\n        }\n        if (isset($data['definitions'])) {\n            $this->getDefinitions()->merge($data['definitions'], $overwrite);\n        }\n        if (isset($data['paths'])) {\n            $this->getPaths()->merge($data['paths'], $overwrite);\n        }\n\n        $this->mergeConsumes($data, $overwrite);\n        $this->mergeExtensions($data, $overwrite);\n        $this->mergeExternalDocs($data, $overwrite);\n        $this->mergeProduces($data, $overwrite);\n        $this->mergeResponses($data, $overwrite);\n        $this->mergeSchemes($data, $overwrite);\n        $this->mergeSecurity($data, $overwrite);\n        $this->mergeTags($data, $overwrite);\n\n        foreach ($data['parameters'] ?? [] as $name => $def) {\n            $this->parameters[$name] = new Parameter($def);\n        }\n\n        foreach ($data['securityDefinitions'] ?? [] as $name => $def) {\n            $this->securityDefinitions[$name] = new SecurityScheme($def);\n        }\n    }\n\n    protected function doExport(): array\n    {\n        return [\n            'swagger' => '2.0',\n            'info' => $this->info,\n            'host' => $this->host,\n            'basePath' => $this->basePath,\n            'schemes' => $this->getSchemes() ?: null,\n            'consumes' => $this->getConsumes() ?: null,\n            'produces' => $this->getProduces() ?: null,\n            'paths' => $this->paths,\n            'definitions' => $this->definitions,\n            'parameters' => $this->parameters ?: null,\n            'responses' => $this->responses,\n            'tags' => $this->getTags() ?: null,\n            'externalDocs' => $this->externalDocs,\n            'securityDefinitions' => $this->securityDefinitions ?: null,\n            'security' => $this->getSecurity(),\n        ];\n    }\n\n    /**\n     * @return string\n     */\n    public function getVersion(): string\n    {\n        return '2.0';\n    }\n\n    /**\n     * @return Info\n     */\n    public function getInfo()\n    {\n        return $this->info;\n    }\n\n    /**\n     * @return string\n     */\n    public function getHost()\n    {\n        return $this->host;\n    }\n\n    /**\n     * @param string $host\n     */\n    public function setHost($host): self\n    {\n        $this->host = $host;\n\n        return $this;\n    }\n\n    /**\n     * @return string\n     */\n    public function getBasePath()\n    {\n        return $this->basePath;\n    }\n\n    /**\n     * @param string $basePath\n     *\n     * @return $this\n     */\n    public function setBasePath($basePath)\n    {\n        $this->basePath = $basePath;\n\n        return $this;\n    }\n\n    /**\n     * @return Paths\n     */\n    public function getPaths()\n    {\n        return $this->paths;\n    }\n\n    /**\n     * @return Definitions\n     */\n    public function getDefinitions()\n    {\n        return $this->definitions;\n    }\n\n    /**\n     * @return array\n     */\n    public function getSecurityDefinitions()\n    {\n        return $this->securityDefinitions;\n    }\n\n    /**\n     * @return array\n     */\n    public function getParameters()\n    {\n        return $this->parameters;\n    }\n\n    /**\n     * @param array $parameters\n     */\n    public function setParameters(array $parameters): self\n    {\n        $this->parameters = $parameters;\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "src/Tag.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger;\n\nuse EXSyst\\Component\\Swagger\\Parts\\DescriptionPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ExtensionPart;\nuse EXSyst\\Component\\Swagger\\Parts\\ExternalDocsPart;\n\nfinal class Tag extends AbstractModel\n{\n    use DescriptionPart;\n    use ExternalDocsPart;\n    use ExtensionPart;\n\n    private $name;\n\n    public function __construct($data)\n    {\n        $data = $this->normalize($data);\n        if (!isset($data['name'])) {\n            throw new \\InvalidArgumentException('A tag must have a name.');\n        }\n\n        $this->name = $data['name'];\n        $this->merge($data);\n    }\n\n    protected function doMerge($data, $overwrite = false)\n    {\n        $this->mergeDescription($data, $overwrite);\n        $this->mergeExtensions($data, $overwrite);\n        $this->mergeExternalDocs($data, $overwrite);\n    }\n\n    public function toArray()\n    {\n        $return = parent::toArray();\n        if (1 === count($return)) {\n            return $return['name'];\n        }\n\n        return $return;\n    }\n\n    protected function doExport(): array\n    {\n        return [\n            'name' => $this->name,\n            'description' => $this->description,\n            'externalDocs' => $this->externalDocs,\n        ];\n    }\n\n    /**\n     * @return string\n     */\n    public function getName(): string\n    {\n        return $this->name;\n    }\n\n    /**\n     * @param string|array $data\n     *\n     * @return array\n     */\n    protected function normalize($data): array\n    {\n        if (is_string($data)) {\n            return [\n                'name' => $data,\n            ];\n        }\n\n        return parent::normalize($data);\n    }\n}\n"
  },
  {
    "path": "src/Util/MergeHelper.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\Util;\n\n/**\n * @internal\n */\nclass MergeHelper\n{\n    /**\n     * @param string|int|array|null $original\n     * @param string|int|array|null $external\n     * @param bool                  $overwrite\n     */\n    public static function mergeFields(&$original, $external, $overwrite)\n    {\n        if ($overwrite) {\n            $original = $external ?? $original;\n        } else {\n            $original = $original ?? $external;\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BasicAuthTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\tests;\n\nuse EXSyst\\Component\\Swagger\\Swagger;\nuse PHPUnit\\Framework\\TestCase;\n\nclass BasicAuthTest extends TestCase\n{\n    private function fileToArray($filename)\n    {\n        return json_decode(file_get_contents($filename), true);\n    }\n\n    public function testUser()\n    {\n        $filename = __DIR__.'/fixtures/basic-auth.json';\n        $swagger = Swagger::fromFile($filename);\n\n        $this->assertEquals($this->fileToArray($filename), $swagger->toArray());\n    }\n}\n"
  },
  {
    "path": "tests/CollectionsTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\tests;\n\nuse EXSyst\\Component\\Swagger\\Collections\\Definitions;\nuse EXSyst\\Component\\Swagger\\Collections\\Parameters;\nuse EXSyst\\Component\\Swagger\\Collections\\Paths;\nuse EXSyst\\Component\\Swagger\\Collections\\Responses;\nuse EXSyst\\Component\\Swagger\\Operation;\nuse EXSyst\\Component\\Swagger\\Parameter;\nuse EXSyst\\Component\\Swagger\\Path;\nuse EXSyst\\Component\\Swagger\\Response;\nuse EXSyst\\Component\\Swagger\\Schema;\nuse EXSyst\\Component\\Swagger\\Swagger;\nuse PHPUnit\\Framework\\TestCase;\n\nclass CollectionsTest extends TestCase\n{\n    public function testDefinitions()\n    {\n        $swagger = new Swagger();\n        $definitions = $swagger->getDefinitions();\n\n        $this->assertInstanceOf(Definitions::class, $definitions);\n        $this->assertNull($definitions->toArray());\n        $this->assertFalse($definitions->has('User'));\n\n        $user = new Schema();\n        $definitions->set('User', $user);\n        $this->assertCount(1, $definitions->toArray());\n        $this->assertTrue($definitions->has('User'));\n        $this->assertSame($user, $definitions->get('User'));\n\n        $this->assertInternalType('array', $definitions->toArray()['User']);\n\n        $definitions->remove('User');\n        $this->assertNull($definitions->toArray());\n        $this->assertFalse($definitions->has('User'));\n    }\n\n    public function testPaths()\n    {\n        $swagger = new Swagger();\n        $paths = $swagger->getPaths();\n\n        $this->assertInstanceOf(Paths::class, $paths);\n        $this->assertNull($paths->toArray());\n        $this->assertFalse($paths->has('/pets'));\n\n        $pets = new Path();\n        $paths->set('/pets', $pets);\n\n        $this->assertCount(1, $paths->toArray());\n        $this->assertTrue($paths->has('/pets'));\n        $this->assertSame($pets, $paths->get('/pets'));\n\n        $this->assertInternalType('array', $paths->toArray()['/pets']);\n\n        $paths->remove('/pets');\n        $this->assertNull($paths->toArray());\n        $this->assertFalse($paths->has('/pets'));\n    }\n\n    public function testParameters()\n    {\n        $path = new Path();\n        $parameters = $path->getOperation('get')->getParameters();\n\n        $this->assertInstanceOf(Parameters::class, $parameters);\n        $this->assertNull($parameters->toArray());\n\n        $id = new Parameter([\n            'name' => 'id',\n            'in' => 'path',\n        ]);\n        $parameters->add($id);\n        $this->assertCount(1, $parameters->toArray());\n        $this->assertTrue($parameters->has('id', 'path'));\n\n        $id2 = new Parameter([\n            'name' => 'id',\n            'in' => 'body',\n        ]);\n        $parameters->add($id2);\n        $this->assertCount(2, $parameters->toArray());\n        $this->assertTrue($parameters->has('id', 'body'));\n        $this->assertSame($id, $parameters->get('id', 'path'));\n        $this->assertSame($id2, $parameters->get('id', 'body'));\n\n        $parameter = $parameters->get('bar', 'query');\n        $this->assertEquals('bar', $parameter->getName());\n        $this->assertEquals('query', $parameter->getIn());\n\n        $this->assertInternalType('array', $parameters->toArray()[0]);\n        $this->assertInternalType('array', $parameters->toArray()[1]);\n\n        $parameters->remove($id);\n        $parameters->remove($id2);\n        $parameters->remove($parameter);\n        $this->assertNull($parameters->toArray());\n\n        // test $ref\n        $parameters->setRef('#/definitions/id');\n        $this->assertEquals(['$ref' => '#/definitions/id'], $parameters->toArray());\n    }\n\n    public function testResponses()\n    {\n        $operation = new Operation();\n        $responses = $operation->getResponses();\n\n        $this->assertInstanceOf(Responses::class, $responses);\n        $this->assertCount(0, $responses->toArray());\n        $this->assertFalse($responses->has('200'));\n\n        $ok = new Response();\n        $responses->set('200', $ok);\n        $this->assertCount(1, $responses->toArray());\n        $this->assertTrue($responses->has('200'));\n        $this->assertInstanceOf(Response::class, $responses->get('200'));\n        $this->assertSame($ok, $responses->get('200'));\n\n        $this->assertInternalType('array', $responses->toArray()['200']);\n\n        $responses->remove('200');\n        $this->assertCount(0, $responses->toArray());\n        $this->assertFalse($responses->has('200'));\n    }\n}\n"
  },
  {
    "path": "tests/KeekoTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\tests;\n\nuse EXSyst\\Component\\Swagger\\Swagger;\nuse PHPUnit\\Framework\\TestCase;\n\nclass KeekoTest extends TestCase\n{\n    private function fileToArray($filename)\n    {\n        return json_decode(file_get_contents($filename), true);\n    }\n\n    public function testUser()\n    {\n        $filename = __DIR__.'/fixtures/keeko-user.json';\n        $swagger = Swagger::fromFile($filename);\n\n        $this->assertEquals($this->fileToArray($filename), $swagger->toArray());\n    }\n}\n"
  },
  {
    "path": "tests/PetstoreTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\tests;\n\nuse EXSyst\\Component\\Swagger\\Schema;\nuse EXSyst\\Component\\Swagger\\Swagger;\nuse PHPUnit\\Framework\\TestCase;\n\nclass PetstoreTest extends TestCase\n{\n    private function fileToArray($filename)\n    {\n        return json_decode(file_get_contents($filename), true);\n    }\n\n    public function testMinimal()\n    {\n        $filename = __DIR__.'/fixtures/petstore-minimal.json';\n        $swagger = Swagger::fromFile($filename);\n\n        $this->assertEquals($this->fileToArray($filename), $swagger->toArray());\n    }\n\n    public function testSimple()\n    {\n        $filename = __DIR__.'/fixtures/petstore-simple.json';\n        $swagger = Swagger::fromFile($filename);\n\n        $this->assertEquals($this->fileToArray($filename), $swagger->toArray());\n    }\n\n    public function testParameterRefs()\n    {\n        $filename = __DIR__.'/fixtures/petstore-parameter-refs.json';\n        $swagger = Swagger::fromFile($filename);\n\n        $this->assertEquals($this->fileToArray($filename), $swagger->toArray());\n    }\n\n    public function testPetstore()\n    {\n        $filename = __DIR__.'/fixtures/petstore.json';\n        $swagger = Swagger::fromFile($filename);\n\n        $this->assertEquals($this->fileToArray($filename), $swagger->toArray());\n\n        $responses = $swagger->getPaths()->get('/pets')->getOperation('get')->getResponses();\n        $headers = $responses->get('200')->getHeaders();\n\n        $this->assertEquals(1, count($headers->toArray()));\n        $this->assertTrue($headers->has('x-expires'));\n        $expires = $headers->get('x-expires');\n\n        $this->assertEquals('string', $expires->getType());\n\n        $headers->remove('x-expires');\n        $this->assertNull($headers->toArray());\n        $this->assertFalse($headers->has('x-expires'));\n\n        $headers->set('x-expires', $expires);\n        $this->assertCount(1, $headers->toArray());\n        $this->assertTrue($headers->has('x-expires'));\n    }\n\n    public function testExpanded()\n    {\n        $filename = __DIR__.'/fixtures/petstore-expanded.json';\n        $swagger = Swagger::fromFile($filename);\n\n        $this->assertEquals($this->fileToArray($filename), $swagger->toArray());\n    }\n\n    public function testExternalDocs()\n    {\n        $filename = __DIR__.'/fixtures/petstore-with-external-docs.json';\n        $swagger = Swagger::fromFile($filename);\n\n        $this->assertEquals($this->fileToArray($filename), $swagger->toArray());\n\n        $external = $swagger->getExternalDocs();\n        $this->assertEquals('find more info here', $external->getDescription());\n        $this->assertEquals('https://Swagger.io/about', $external->getUrl());\n\n        $info = $swagger->getInfo();\n        $this->assertEquals('1.0.0', $info->getVersion());\n        $this->assertEquals('Swagger Petstore', $info->getTitle());\n        $this->assertEquals('A sample API that uses a petstore as an example to demonstrate features in the Swagger-2.0 specification', $info->getDescription());\n        $this->assertEquals('http://Swagger.io/terms/', $info->getTerms());\n\n        $this->assertEquals('1.0.1', $info->setVersion('1.0.1')->getVersion());\n        $this->assertEquals('Pets', $info->setTitle('Pets')->getTitle());\n        $this->assertEquals('desc', $info->setDescription('desc')->getDescription());\n        $this->assertEquals('T-O-S', $info->setTerms('T-O-S')->getTerms());\n\n        $contact = $info->getContact();\n        $this->assertEquals('Swagger API Team', $contact->getName());\n        $this->assertEquals('apiteam@Swagger.io', $contact->getEmail());\n        $this->assertEquals('http://Swagger.io', $contact->getUrl());\n\n        $this->assertEquals('Swaggers', $contact->setName('Swaggers')->getName());\n        $this->assertEquals('team@Swagger.io', $contact->setEmail('team@Swagger.io')->getEmail());\n        $this->assertEquals('https://Swagger.io', $contact->setUrl('https://Swagger.io')->getUrl());\n\n        $license = $info->getLicense();\n        $this->assertEquals('MIT', $license->getName());\n        $this->assertEquals('http://github.com/gruntjs/grunt/blob/master/LICENSE-MIT', $license->getUrl());\n\n        $this->assertEquals('APL', $license->setName('APL')->getName());\n        $this->assertEquals('https://www.apache.org/licenses/LICENSE-2.0', $license->setUrl('https://www.apache.org/licenses/LICENSE-2.0')->getUrl());\n    }\n\n    public function testDictionaries()\n    {\n        $filename = __DIR__.'/fixtures/petstore-dictionaries.json';\n        $swagger = Swagger::fromFile($filename);\n\n        $swaggerAsArray = $swagger->toArray();\n\n        $this->assertEquals($this->fileToArray($filename), $swaggerAsArray);\n        $this->assertInstanceOf(Schema::class, $swagger->getDefinitions()->get('Pet')->getProperties()->get('sub-object')->getAdditionalProperties());\n        $this->assertSame(true, $swaggerAsArray['definitions']['Pet']['properties']['sub-object']['additionalProperties']);\n        $this->assertSame(null, $swagger->getDefinitions()->get('Pet')->getProperties()->get('sub-object')->getAdditionalProperties()->getType());\n        $this->assertSame(null, $swagger->getDefinitions()->get('Pet')->getProperties()->get('sub-object')->getAdditionalProperties()->getAdditionalProperties());\n        $this->assertSame('string', $swagger->getDefinitions()->get('Pet')->getProperties()->get('another-sub-object')->getAdditionalProperties()->getType());\n        $this->assertSame(null, $swagger->getDefinitions()->get('Pet')->getProperties()->get('another-sub-object')->getAdditionalProperties()->getAdditionalProperties());\n        $this->assertSame('object', $swagger->getDefinitions()->get('Pet')->getProperties()->get('nested-sub-objects')->getAdditionalProperties()->getType());\n        $this->assertInstanceOf(Schema::class, $swagger->getDefinitions()->get('Pet')->getProperties()->get('nested-sub-objects')->getAdditionalProperties()->getAdditionalProperties());\n        $this->assertSame('string', $swagger->getDefinitions()->get('Pet')->getProperties()->get('nested-sub-objects')->getAdditionalProperties()->getAdditionalProperties()->getType());\n        $this->assertSame('string', $swaggerAsArray['definitions']['Pet']['properties']['nested-sub-objects']['additionalProperties']['additionalProperties']['type']);\n        $this->assertSame('array', $swagger->getDefinitions()->get('Pet')->getProperties()->get('children')->getType());\n        $this->assertSame('array', $swaggerAsArray['definitions']['Pet']['properties']['children']['type']);\n        $this->assertInstanceOf(Schema::class, $swagger->getDefinitions()->get('Pet')->getProperties()->get('children')->getItems());\n        $this->assertSame('#/definitions/Pet', $swagger->getDefinitions()->get('Pet')->getProperties()->get('children')->getItems()->getRef());\n        $this->assertSame('#/definitions/Pet', $swaggerAsArray['definitions']['Pet']['properties']['children']['items']['$ref']);\n        $this->assertSame('object', $swaggerAsArray['definitions']['Pet']['properties']['child-pet']['type']);\n        $this->assertInstanceOf(Schema::class, $swagger->getDefinitions()->get('Pet')->getProperties()->get('child-pet')->getProperties()->get('name'));\n        $this->assertSame('string', $swagger->getDefinitions()->get('Pet')->getProperties()->get('child-pet')->getAdditionalProperties()->getProperties()->get('name')->getType());\n        $this->assertSame('string', $swaggerAsArray['definitions']['Pet']['properties']['child-pet']['additionalProperties']['properties']['name']['type']);\n        $this->assertSame('object', $swagger->getDefinitions()->get('Pet')->getProperties()->get('child-pet')->getAdditionalProperties()->getProperties()->get('child-pet-children')->getType());\n        $this->assertSame('string', $swagger->getDefinitions()->get('Pet')->getProperties()->get('child-pet')->getAdditionalProperties()->getProperties()->get('child-pet-children')->getAdditionalProperties()->getType());\n        $this->assertSame('object', $swagger->getDefinitions()->get('Pet')->getProperties()->get('child-pet')->getAdditionalProperties()->getProperties()->get('sub-object')->getType());\n        $this->assertSame(true, $swaggerAsArray['definitions']['Pet']['properties']['child-pet']['additionalProperties']['properties']['sub-object']['additionalProperties']);\n    }\n}\n"
  },
  {
    "path": "tests/SwaggerTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Swagger package.\n *\n * (c) EXSyst\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace EXSyst\\Component\\Swagger\\tests;\n\nuse EXSyst\\Component\\Swagger\\Swagger;\nuse PHPUnit\\Framework\\TestCase;\n\nclass SwaggerTest extends TestCase\n{\n    public function testVersion()\n    {\n        $swagger = new Swagger();\n        $this->assertEquals('2.0', $swagger->getVersion());\n    }\n\n    public function testBasics()\n    {\n        $swagger = new Swagger();\n        $swagger->setBasePath('/api');\n        $swagger->setHost('http://example.com');\n\n        $this->assertEquals('/api', $swagger->getBasePath());\n        $this->assertEquals('http://example.com', $swagger->getHost());\n\n        $this->assertEquals([\n            'swagger' => '2.0',\n            'host' => 'http://example.com',\n            'basePath' => '/api',\n        ], $swagger->toArray());\n    }\n}\n"
  },
  {
    "path": "tests/fixtures/basic-auth.json",
    "content": "{\n\t\"swagger\": \"2.0\",\n\t\"info\": {\n\t\t\"version\": \"1.0.0\",\n\t\t\"title\": \"Basic Auth Example\",\n\t\t\"description\": \"An example for how to use Basic Auth with Swagger.\\nServer code is available [here](https://github.com/mohsen1/basic-auth-server). It's running on Heroku.\\n\\n**User Name and Password**\\n* User Name: `user`\\n* Password: `pass`\\n\"\n\t},\n\t\"host\": \"basic-auth-server.herokuapp.com\",\n\t\"schemes\": [\n\t\t\"http\",\n\t\t\"https\"\n\t],\n\t\"securityDefinitions\": {\n\t\t\"basicAuth\": {\n\t\t\t\"type\": \"basic\",\n\t\t\t\"description\": \"HTTP Basic Authentication. Works over `HTTP` and `HTTPS`\"\n\t\t}\n\t},\n\t\"paths\": {\n\t\t\"/\": {\n\t\t\t\"get\": {\n\t\t\t\t\"security\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"basicAuth\": []\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"responses\": {\n\t\t\t\t\t\"200\": {\n\t\t\t\t\t\t\"description\": \"Will send `Authenticated` if authentication is succesful, otherwise it will send `Unauthorized`\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tests/fixtures/keeko-user.json",
    "content": "{\n\t\"swagger\": \"2.0\",\n\t\"paths\": {\n\t\t\"/users\": {\n\t\t\t\"get\": {\n\t\t\t\t\"description\": \"List all users\",\n\t\t\t\t\"operationId\": \"user-list\",\n\t\t\t\t\"produces\": [\n\t\t\t\t\t\"application/json\"\n\t\t\t\t],\n\t\t\t\t\"responses\": {\n\t\t\t\t\t\"200\": {\n\t\t\t\t\t\t\"description\": \"Array of users\",\n\t\t\t\t\t\t\"schema\": {\n\t\t\t\t\t\t\t\"$ref\": \"#/definitions/PagedUsers\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"post\": {\n\t\t\t\t\"description\": \"Creates an user\",\n\t\t\t\t\"operationId\": \"user-create\",\n\t\t\t\t\"schemes\": [\"https\", \"wss\"],\n\t\t\t\t\"produces\": [\n\t\t\t\t\t\"application/json\"\n\t\t\t\t],\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"body\",\n\t\t\t\t\t\t\"in\": \"body\",\n\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\"description\": \"The new user\",\n\t\t\t\t\t\t\"schema\": {\n\t\t\t\t\t\t\t\"$ref\": \"#/definitions/WritableUser\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"responses\": {\n\t\t\t\t\t\"201\": {\n\t\t\t\t\t\t\"description\": \"user created\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"/users/{id}\": {\n\t\t\t\"get\": {\n\t\t\t\t\"description\": \"Reads an user\",\n\t\t\t\t\"operationId\": \"user-read\",\n\t\t\t\t\"produces\": [\n\t\t\t\t\t\"application/json\"\n\t\t\t\t],\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"id\",\n\t\t\t\t\t\t\"in\": \"path\",\n\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\"description\": \"The user id\",\n\t\t\t\t\t\t\"type\": \"integer\"\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"responses\": {\n\t\t\t\t\t\"200\": {\n\t\t\t\t\t\t\"description\": \"gets the user\",\n\t\t\t\t\t\t\"schema\": {\n\t\t\t\t\t\t\t\"$ref\": \"#/definitions/User\"\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"400\": {\n\t\t\t\t\t\t\"description\": \"Invalid ID supplied\"\n\t\t\t\t\t},\n\t\t\t\t\t\"404\": {\n\t\t\t\t\t\t\"description\": \"No user found\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"put\": {\n\t\t\t\t\"description\": \"Updates an user\",\n\t\t\t\t\"operationId\": \"user-update\",\n\t\t\t\t\"produces\": [\n\t\t\t\t\t\"application/json\"\n\t\t\t\t],\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"id\",\n\t\t\t\t\t\t\"in\": \"path\",\n\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\"description\": \"The user id\",\n\t\t\t\t\t\t\"type\": \"integer\"\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"responses\": {\n\t\t\t\t\t\"200\": {\n\t\t\t\t\t\t\"description\": \"user updated\",\n\t\t\t\t\t\t\"schema\": {\n\t\t\t\t\t\t\t\"$ref\": \"#/definitions/User\"\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"400\": {\n\t\t\t\t\t\t\"description\": \"Invalid ID supplied\"\n\t\t\t\t\t},\n\t\t\t\t\t\"404\": {\n\t\t\t\t\t\t\"description\": \"No user found\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"delete\": {\n\t\t\t\t\"description\": \"Deletes an user\",\n\t\t\t\t\"operationId\": \"user-delete\",\n\t\t\t\t\"produces\": [\n\t\t\t\t\t\"application/json\"\n\t\t\t\t],\n\t\t\t\t\"parameters\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"name\": \"id\",\n\t\t\t\t\t\t\"in\": \"path\",\n\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\"description\": \"The user id\",\n\t\t\t\t\t\t\"type\": \"integer\"\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"responses\": {\n\t\t\t\t\t\"204\": {\n\t\t\t\t\t\t\"description\": \"user deleted\"\n\t\t\t\t\t},\n\t\t\t\t\t\"400\": {\n\t\t\t\t\t\t\"description\": \"Invalid ID supplied\"\n\t\t\t\t\t},\n\t\t\t\t\t\"404\": {\n\t\t\t\t\t\t\"description\": \"No user found\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\t\"definitions\": {\n\t\t\"Meta\": {\n\t\t\t\"properties\": {\n\t\t\t\t\"total\": {\n\t\t\t\t\t\"type\": \"integer\"\n\t\t\t\t},\n\t\t\t\t\"first\": {\n\t\t\t\t\t\"type\": \"integer\"\n\t\t\t\t},\n\t\t\t\t\"next\": {\n\t\t\t\t\t\"type\": \"integer\"\n\t\t\t\t},\n\t\t\t\t\"previous\": {\n\t\t\t\t\t\"type\": \"integer\"\n\t\t\t\t},\n\t\t\t\t\"last\": {\n\t\t\t\t\t\"type\": \"integer\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"PagedUsers\": {\n\t\t\t\"properties\": {\n\t\t\t\t\"users\": {\n\t\t\t\t\t\"type\": \"array\",\n\t\t\t\t\t\"items\": {\n\t\t\t\t\t\t\"$ref\": \"#/definitions/User\"\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"meta\": {\n\t\t\t\t\t\"$ref\": \"#/definitions/Meta\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"WritableUser\": {\n\t\t\t\"properties\": {\n\t\t\t\t\"id\": {\n\t\t\t\t\t\"type\": \"int\"\n\t\t\t\t},\n\t\t\t\t\"login_name\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t},\n\t\t\t\t\"password\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t},\n\t\t\t\t\"given_name\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t},\n\t\t\t\t\"family_name\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t},\n\t\t\t\t\"display_name\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t},\n\t\t\t\t\"email\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t},\n\t\t\t\t\"birthday\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t},\n\t\t\t\t\"sex\": {\n\t\t\t\t\t\"type\": \"int\"\n\t\t\t\t},\n\t\t\t\t\"password_recover_code\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t},\n\t\t\t\t\"password_recover_time\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"User\": {\n\t\t\t\"properties\": {\n\t\t\t\t\"id\": {\n\t\t\t\t\t\"type\": \"int\"\n\t\t\t\t},\n\t\t\t\t\"login_name\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t},\n\t\t\t\t\"password\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t},\n\t\t\t\t\"given_name\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t},\n\t\t\t\t\"family_name\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t},\n\t\t\t\t\"display_name\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t},\n\t\t\t\t\"email\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t},\n\t\t\t\t\"birthday\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t},\n\t\t\t\t\"sex\": {\n\t\t\t\t\t\"type\": \"int\"\n\t\t\t\t},\n\t\t\t\t\"password_recover_code\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t},\n\t\t\t\t\"password_recover_time\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t},\n\t\t\t\t\"created_at\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t},\n\t\t\t\t\"updated_at\": {\n\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tests/fixtures/petstore-dictionaries.json",
    "content": "{\n  \"swagger\": \"2.0\",\n  \"info\": {\n    \"version\": \"1.0.0\",\n    \"title\": \"Swagger Petstore\",\n    \"contact\": {\n      \"name\": \"Swagger API Team\",\n      \"url\": \"http://Swagger.io\"\n    },\n    \"license\": {\n      \"name\": \"Creative Commons 4.0 International\",\n      \"url\": \"http://creativecommons.org/licenses/by/4.0/\"\n    }\n  },\n  \"host\": \"petstore.Swagger.io\",\n  \"basePath\": \"/api\",\n  \"schemes\": [\n    \"http\"\n  ],\n  \"paths\": {\n    \"/pets\": {\n      \"get\": {\n        \"description\": \"Returns all pets from the system that the user has access to\",\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"A list of pets.\",\n            \"schema\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/Pet\"\n              }\n            }\n          }\n        }\n      }\n    }\n  },\n  \"definitions\": {\n    \"Pet\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"sub-object\": {\n          \"type\": \"object\",\n          \"additionalProperties\": true\n        },\n        \"another-sub-object\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"nested-sub-objects\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"object\",\n            \"additionalProperties\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"children\": {\n          \"items\": {\n            \"$ref\": \"#/definitions/Pet\"\n          },\n          \"type\": \"array\"\n        },\n        \"child-pet\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"properties\": {\n              \"name\": {\n                \"type\": \"string\"\n              },\n              \"child-pet-children\": {\n                \"type\": \"object\",\n                \"additionalProperties\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"sub-object\": {\n                \"type\": \"object\",\n                \"additionalProperties\": true\n              }\n            }\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "tests/fixtures/petstore-expanded.json",
    "content": "{\n  \"swagger\": \"2.0\",\n  \"info\": {\n    \"version\": \"1.0.0\",\n    \"title\": \"Swagger Petstore\",\n    \"description\": \"A sample API that uses a petstore as an example to demonstrate features in the Swagger-2.0 specification\",\n    \"termsOfService\": \"http://Swagger.io/terms/\",\n    \"contact\": {\n      \"name\": \"Swagger API Team\",\n      \"email\": \"foo@example.com\",\n      \"url\": \"http://madskristensen.net\"\n    },\n    \"license\": {\n      \"name\": \"MIT\",\n      \"url\": \"http://github.com/gruntjs/grunt/blob/master/LICENSE-MIT\"\n    }\n  },\n  \"host\": \"petstore.Swagger.io\",\n  \"basePath\": \"/api\",\n  \"schemes\": [\n    \"http\"\n  ],\n  \"consumes\": [\n    \"application/json\"\n  ],\n  \"produces\": [\n    \"application/json\"\n  ],\n  \"paths\": {\n    \"/pets\": {\n      \"get\": {\n        \"description\": \"Returns all pets from the system that the user has access to\\nNam sed condimentum est. Maecenas tempor sagittis sapien, nec rhoncus sem sagittis sit amet. Aenean at gravida augue, ac iaculis sem. Curabitur odio lorem, ornare eget elementum nec, cursus id lectus. Duis mi turpis, pulvinar ac eros ac, tincidunt varius justo. In hac habitasse platea dictumst. Integer at adipiscing ante, a sagittis ligula. Aenean pharetra tempor ante molestie imperdiet. Vivamus id aliquam diam. Cras quis velit non tortor eleifend sagittis. Praesent at enim pharetra urna volutpat venenatis eget eget mauris. In eleifend fermentum facilisis. Praesent enim enim, gravida ac sodales sed, placerat id erat. Suspendisse lacus dolor, consectetur non augue vel, vehicula interdum libero. Morbi euismod sagittis libero sed lacinia.\\n\\nSed tempus felis lobortis leo pulvinar rutrum. Nam mattis velit nisl, eu condimentum ligula luctus nec. Phasellus semper velit eget aliquet faucibus. In a mattis elit. Phasellus vel urna viverra, condimentum lorem id, rhoncus nibh. Ut pellentesque posuere elementum. Sed a varius odio. Morbi rhoncus ligula libero, vel eleifend nunc tristique vitae. Fusce et sem dui. Aenean nec scelerisque tortor. Fusce malesuada accumsan magna vel tempus. Quisque mollis felis eu dolor tristique, sit amet auctor felis gravida. Sed libero lorem, molestie sed nisl in, accumsan tempor nisi. Fusce sollicitudin massa ut lacinia mattis. Sed vel eleifend lorem. Pellentesque vitae felis pretium, pulvinar elit eu, euismod sapien.\\n\",\n        \"operationId\": \"findPets\",\n        \"parameters\": [\n          {\n            \"name\": \"tags\",\n            \"in\": \"query\",\n            \"description\": \"tags to filter by\",\n            \"required\": false,\n            \"type\": \"array\",\n            \"collectionFormat\": \"csv\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          {\n            \"name\": \"limit\",\n            \"in\": \"query\",\n            \"description\": \"maximum number of results to return\",\n            \"required\": false,\n            \"type\": \"integer\",\n            \"format\": \"int32\"\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"pet response\",\n            \"schema\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/Pet\"\n              }\n            }\n          },\n          \"default\": {\n            \"description\": \"unexpected error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Error\"\n            }\n          }\n        }\n      },\n      \"post\": {\n        \"description\": \"Creates a new pet in the store.  Duplicates are allowed\",\n        \"operationId\": \"addPet\",\n        \"parameters\": [\n          {\n            \"name\": \"pet\",\n            \"in\": \"body\",\n            \"description\": \"Pet to add to the store\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/NewPet\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"pet response\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Pet\"\n            }\n          },\n          \"default\": {\n            \"description\": \"unexpected error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Error\"\n            }\n          }\n        }\n      }\n    },\n    \"/pets/{id}\": {\n      \"get\": {\n        \"description\": \"Returns a user based on a single ID, if the user does not have access to the pet\",\n        \"operationId\": \"find pet by id\",\n        \"parameters\": [\n          {\n            \"name\": \"id\",\n            \"in\": \"path\",\n            \"description\": \"ID of pet to fetch\",\n            \"required\": true,\n            \"type\": \"integer\",\n            \"format\": \"int64\"\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"pet response\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Pet\"\n            }\n          },\n          \"default\": {\n            \"description\": \"unexpected error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Error\"\n            }\n          }\n        }\n      },\n      \"delete\": {\n        \"description\": \"deletes a single pet based on the ID supplied\",\n        \"operationId\": \"deletePet\",\n        \"parameters\": [\n          {\n            \"name\": \"id\",\n            \"in\": \"path\",\n            \"description\": \"ID of pet to delete\",\n            \"required\": true,\n            \"type\": \"integer\",\n            \"format\": \"int64\"\n          }\n        ],\n        \"responses\": {\n          \"204\": {\n            \"description\": \"pet deleted\"\n          },\n          \"default\": {\n            \"description\": \"unexpected error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Error\"\n            }\n          }\n        }\n      }\n    }\n  },\n  \"definitions\": {\n    \"Pet\": {\n      \"type\": \"object\",\n      \"allOf\": [\n        {\n          \"$ref\": \"#/definitions/NewPet\"\n        },\n        {\n          \"required\": [\n            \"id\"\n          ],\n          \"properties\": {\n            \"id\": {\n              \"type\": \"integer\",\n              \"format\": \"int64\"\n            }\n          }\n        }\n      ]\n    },\n    \"NewPet\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"tag\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"Error\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"code\",\n        \"message\"\n      ],\n      \"properties\": {\n        \"code\": {\n          \"type\": \"integer\",\n          \"format\": \"int32\"\n        },\n        \"message\": {\n          \"type\": \"string\"\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "tests/fixtures/petstore-minimal.json",
    "content": "{\n  \"swagger\": \"2.0\",\n  \"info\": {\n    \"version\": \"1.0.0\",\n    \"title\": \"Swagger Petstore\",\n    \"description\": \"A sample API that uses a petstore as an example to demonstrate features in the Swagger-2.0 specification\",\n    \"termsOfService\": \"http://Swagger.io/terms/\",\n    \"contact\": {\n      \"name\": \"Swagger API Team\"\n    },\n    \"license\": {\n      \"name\": \"MIT\"\n    }\n  },\n  \"host\": \"petstore.Swagger.io\",\n  \"basePath\": \"/api\",\n  \"schemes\": [\n    \"http\"\n  ],\n  \"consumes\": [\n    \"application/json\"\n  ],\n  \"produces\": [\n    \"application/json\"\n  ],\n  \"paths\": {\n    \"/pets\": {\n      \"get\": {\n        \"description\": \"Returns all pets from the system that the user has access to\",\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"A list of pets.\",\n            \"schema\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/Pet\"\n              }\n            }\n          }\n        }\n      }\n    }\n  },\n  \"definitions\": {\n    \"Pet\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"id\",\n        \"name\"\n      ],\n      \"properties\": {\n        \"id\": {\n          \"type\": \"integer\",\n          \"format\": \"int64\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"tag\": {\n          \"type\": \"string\"\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "tests/fixtures/petstore-parameter-refs.json",
    "content": "{\n  \"swagger\": \"2.0\",\n  \"info\": {\n    \"version\": \"1.0.0\",\n    \"title\": \"Swagger Petstore\",\n    \"description\": \"A sample API that uses a petstore as an example to demonstrate features in the Swagger-2.0 specification\",\n    \"termsOfService\": \"http://Swagger.io/terms/\",\n    \"contact\": {\n      \"name\": \"Swagger API Team\"\n    },\n    \"license\": {\n      \"name\": \"MIT\"\n    }\n  },\n  \"host\": \"petstore.Swagger.io\",\n  \"basePath\": \"/api\",\n  \"schemes\": [\n    \"http\"\n  ],\n  \"consumes\": [\n    \"application/json\"\n  ],\n  \"produces\": [\n    \"application/json\"\n  ],\n  \"paths\": {\n    \"/pets\": {\n      \"get\": {\n        \"description\": \"Returns all pets from the system that the user has access to\",\n        \"operationId\": \"findPets\",\n        \"produces\": [\n          \"application/json\",\n          \"application/xml\",\n          \"text/xml\",\n          \"text/html\"\n        ],\n        \"parameters\": [\n          {\n            \"name\": \"tags\",\n            \"in\": \"query\",\n            \"description\": \"tags to filter by\",\n            \"required\": false,\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            },\n            \"collectionFormat\": \"csv\"\n          },\n          {\n            \"name\": \"limit\",\n            \"in\": \"query\",\n            \"description\": \"maximum number of results to return\",\n            \"required\": false,\n            \"type\": \"integer\",\n            \"format\": \"int32\"\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"pet response\",\n            \"schema\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/Pet\"\n              }\n            }\n          },\n          \"default\": {\n            \"description\": \"unexpected error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorModel\"\n            }\n          }\n        }\n      },\n      \"post\": {\n        \"description\": \"Creates a new pet in the store.  Duplicates are allowed\",\n        \"operationId\": \"addPet\",\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"parameters\": [\n          {\n            \"name\": \"pet\",\n            \"in\": \"body\",\n            \"description\": \"Pet to add to the store\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/PetInput\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"pet response\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Pet\"\n            }\n          },\n          \"default\": {\n            \"description\": \"unexpected error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorModel\"\n            }\n          }\n        }\n      }\n    },\n    \"/pets/{id}\": {\n      \"get\": {\n        \"description\": \"Returns a user based on a single ID, if the user does not have access to the pet\",\n        \"operationId\": \"findPetById\",\n        \"produces\": [\n          \"application/json\",\n          \"application/xml\",\n          \"text/xml\",\n          \"text/html\"\n        ],\n        \"parameters\": [\n          { \"$ref\": \"#/parameters/petId\" }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"pet response\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Pet\"\n            }\n          },\n          \"default\": {\n            \"description\": \"unexpected error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorModel\"\n            }\n          }\n        }\n      },\n      \"delete\": {\n        \"description\": \"deletes a single pet based on the ID supplied\",\n        \"operationId\": \"deletePet\",\n        \"parameters\": [\n          { \"$ref\": \"#/parameters/petId\" }\n        ],\n        \"responses\": {\n          \"204\": {\n            \"description\": \"pet deleted\"\n          },\n          \"default\": {\n            \"description\": \"unexpected error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorModel\"\n            }\n          }\n        }\n      }\n    }\n  },\n  \"definitions\": {\n    \"Pet\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"id\",\n        \"name\"\n      ],\n      \"properties\": {\n        \"id\": {\n          \"type\": \"integer\",\n          \"format\": \"int64\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"tag\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"PetInput\": {\n      \"type\": \"object\",\n      \"allOf\": [\n        {\n          \"$ref\": \"#/definitions/Pet\"\n        },\n        {\n          \"required\": [\n            \"name\"\n          ],\n          \"properties\": {\n            \"id\": {\n              \"type\": \"integer\",\n              \"format\": \"int64\"\n            }\n          }\n        }\n      ]\n    },\n    \"ErrorModel\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"code\",\n        \"message\"\n      ],\n      \"properties\": {\n        \"code\": {\n          \"type\": \"integer\",\n          \"format\": \"int32\"\n        },\n        \"message\": {\n          \"type\": \"string\"\n        }\n      }\n    }\n  },\n  \"parameters\": {\n    \"petId\": {\n      \"name\": \"id\",\n      \"in\": \"path\",\n      \"description\": \"Pet ID\",\n      \"required\": true,\n      \"type\": \"integer\",\n      \"format\": \"int64\"\n    }\n  }\n}\n"
  },
  {
    "path": "tests/fixtures/petstore-simple.json",
    "content": "{\n  \"swagger\": \"2.0\",\n  \"info\": {\n    \"version\": \"1.0.0\",\n    \"title\": \"Swagger Petstore\",\n    \"description\": \"A sample API that uses a petstore as an example to demonstrate features in the Swagger-2.0 specification\",\n    \"termsOfService\": \"http://Swagger.io/terms/\",\n    \"contact\": {\n      \"name\": \"Swagger API Team\"\n    },\n    \"license\": {\n      \"name\": \"MIT\"\n    }\n  },\n  \"host\": \"petstore.Swagger.io\",\n  \"basePath\": \"/api\",\n  \"schemes\": [\n    \"http\"\n  ],\n  \"consumes\": [\n    \"application/json\"\n  ],\n  \"produces\": [\n    \"application/json\"\n  ],\n  \"paths\": {\n    \"/pets\": {\n      \"get\": {\n        \"description\": \"Returns all pets from the system that the user has access to\",\n        \"operationId\": \"findPets\",\n        \"produces\": [\n          \"application/json\",\n          \"application/xml\",\n          \"text/xml\",\n          \"text/html\"\n        ],\n        \"parameters\": [\n          {\n            \"name\": \"tags\",\n            \"in\": \"query\",\n            \"description\": \"tags to filter by\",\n            \"required\": false,\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            },\n            \"collectionFormat\": \"csv\"\n          },\n          {\n            \"name\": \"limit\",\n            \"in\": \"query\",\n            \"description\": \"maximum number of results to return\",\n            \"required\": false,\n            \"type\": \"integer\",\n            \"format\": \"int32\"\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"pet response\",\n            \"schema\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/Pet\"\n              }\n            }\n          },\n          \"default\": {\n            \"description\": \"unexpected error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorModel\"\n            }\n          }\n        }\n      },\n      \"post\": {\n        \"description\": \"Creates a new pet in the store.  Duplicates are allowed\",\n        \"operationId\": \"addPet\",\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"parameters\": [\n          {\n            \"name\": \"pet\",\n            \"in\": \"body\",\n            \"description\": \"Pet to add to the store\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/PetInput\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"pet response\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Pet\"\n            }\n          },\n          \"default\": {\n            \"description\": \"unexpected error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorModel\"\n            }\n          }\n        }\n      }\n    },\n    \"/pets/{id}\": {\n      \"get\": {\n        \"description\": \"Returns a user based on a single ID, if the user does not have access to the pet\",\n        \"operationId\": \"findPetById\",\n        \"produces\": [\n          \"application/json\",\n          \"application/xml\",\n          \"text/xml\",\n          \"text/html\"\n        ],\n        \"parameters\": [\n          {\n            \"name\": \"id\",\n            \"in\": \"path\",\n            \"description\": \"ID of pet to fetch\",\n            \"required\": true,\n            \"type\": \"integer\",\n            \"format\": \"int64\"\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"pet response\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Pet\"\n            }\n          },\n          \"default\": {\n            \"description\": \"unexpected error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorModel\"\n            }\n          }\n        }\n      },\n      \"delete\": {\n        \"description\": \"deletes a single pet based on the ID supplied\",\n        \"operationId\": \"deletePet\",\n        \"parameters\": [\n          {\n            \"name\": \"id\",\n            \"in\": \"path\",\n            \"description\": \"ID of pet to delete\",\n            \"required\": true,\n            \"type\": \"integer\",\n            \"format\": \"int64\"\n          }\n        ],\n        \"responses\": {\n          \"204\": {\n            \"description\": \"pet deleted\"\n          },\n          \"default\": {\n            \"description\": \"unexpected error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorModel\"\n            }\n          }\n        }\n      }\n    }\n  },\n  \"definitions\": {\n    \"Pet\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"id\",\n        \"name\"\n      ],\n      \"properties\": {\n        \"id\": {\n          \"type\": \"integer\",\n          \"format\": \"int64\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"tag\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"PetInput\": {\n      \"type\": \"object\",\n      \"allOf\": [\n        {\n          \"$ref\": \"#/definitions/Pet\"\n        },\n        {\n          \"required\": [\n            \"name\"\n          ],\n          \"properties\": {\n            \"id\": {\n              \"type\": \"integer\",\n              \"format\": \"int64\"\n            }\n          }\n        }\n      ]\n    },\n    \"ErrorModel\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"code\",\n        \"message\"\n      ],\n      \"properties\": {\n        \"code\": {\n          \"type\": \"integer\",\n          \"format\": \"int32\"\n        },\n        \"message\": {\n          \"type\": \"string\"\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "tests/fixtures/petstore-with-external-docs.json",
    "content": "{\n  \"swagger\": \"2.0\",\n  \"info\": {\n    \"version\": \"1.0.0\",\n    \"title\": \"Swagger Petstore\",\n    \"description\": \"A sample API that uses a petstore as an example to demonstrate features in the Swagger-2.0 specification\",\n    \"termsOfService\": \"http://Swagger.io/terms/\",\n    \"contact\": {\n      \"name\": \"Swagger API Team\",\n      \"email\": \"apiteam@Swagger.io\",\n      \"url\": \"http://Swagger.io\"\n    },\n    \"license\": {\n      \"name\": \"MIT\",\n      \"url\": \"http://github.com/gruntjs/grunt/blob/master/LICENSE-MIT\"\n    }\n  },\n  \"externalDocs\": {\n    \"description\": \"find more info here\",\n    \"url\": \"https://Swagger.io/about\"\n  },\n  \"host\": \"petstore.Swagger.io\",\n  \"basePath\": \"/api\",\n  \"schemes\": [\n    \"http\"\n  ],\n  \"consumes\": [\n    \"application/json\"\n  ],\n  \"produces\": [\n    \"application/json\"\n  ],\n  \"paths\": {\n    \"/pets\": {\n      \"get\": {\n        \"description\": \"Returns all pets from the system that the user has access to\",\n        \"operationId\": \"findPets\",\n        \"externalDocs\": {\n          \"description\": \"find more info here\",\n          \"url\": \"https://Swagger.io/about\"\n        },\n        \"produces\": [\n          \"application/json\",\n          \"application/xml\",\n          \"text/xml\",\n          \"text/html\"\n        ],\n        \"parameters\": [\n          {\n            \"name\": \"tags\",\n            \"in\": \"query\",\n            \"description\": \"tags to filter by\",\n            \"required\": false,\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            },\n            \"collectionFormat\": \"csv\"\n          },\n          {\n            \"name\": \"limit\",\n            \"in\": \"query\",\n            \"description\": \"maximum number of results to return\",\n            \"required\": false,\n            \"type\": \"integer\",\n            \"format\": \"int32\"\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"pet response\",\n            \"schema\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/Pet\"\n              }\n            }\n          },\n          \"default\": {\n            \"description\": \"unexpected error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorModel\"\n            }\n          }\n        }\n      },\n      \"post\": {\n        \"description\": \"Creates a new pet in the store.  Duplicates are allowed\",\n        \"operationId\": \"addPet\",\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"parameters\": [\n          {\n            \"name\": \"pet\",\n            \"in\": \"body\",\n            \"description\": \"Pet to add to the store\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/NewPet\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"pet response\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Pet\"\n            }\n          },\n          \"default\": {\n            \"description\": \"unexpected error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorModel\"\n            }\n          }\n        }\n      }\n    },\n    \"/pets/{id}\": {\n      \"get\": {\n        \"description\": \"Returns a user based on a single ID, if the user does not have access to the pet\",\n        \"operationId\": \"findPetById\",\n        \"produces\": [\n          \"application/json\",\n          \"application/xml\",\n          \"text/xml\",\n          \"text/html\"\n        ],\n        \"parameters\": [\n          {\n            \"name\": \"id\",\n            \"in\": \"path\",\n            \"description\": \"ID of pet to fetch\",\n            \"required\": true,\n            \"type\": \"integer\",\n            \"format\": \"int64\"\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"pet response\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Pet\"\n            }\n          },\n          \"default\": {\n            \"description\": \"unexpected error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorModel\"\n            }\n          }\n        }\n      },\n      \"delete\": {\n        \"description\": \"deletes a single pet based on the ID supplied\",\n        \"operationId\": \"deletePet\",\n        \"parameters\": [\n          {\n            \"name\": \"id\",\n            \"in\": \"path\",\n            \"description\": \"ID of pet to delete\",\n            \"required\": true,\n            \"type\": \"integer\",\n            \"format\": \"int64\"\n          }\n        ],\n        \"responses\": {\n          \"204\": {\n            \"description\": \"pet deleted\"\n          },\n          \"default\": {\n            \"description\": \"unexpected error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorModel\"\n            }\n          }\n        }\n      }\n    }\n  },\n  \"definitions\": {\n    \"Pet\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"id\",\n        \"name\"\n      ],\n      \"externalDocs\": {\n        \"description\": \"find more info here\",\n        \"url\": \"https://Swagger.io/about\"\n      },\n      \"properties\": {\n        \"id\": {\n          \"type\": \"integer\",\n          \"format\": \"int64\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"tag\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"NewPet\": {\n      \"type\": \"object\",\n      \"allOf\": [\n        {\n          \"$ref\": \"#/definitions/Pet\"\n        },\n        {\n          \"required\": [\n            \"name\"\n          ],\n          \"properties\": {\n            \"id\": {\n              \"type\": \"integer\",\n              \"format\": \"int64\"\n            }\n          }\n        }\n      ]\n    },\n    \"ErrorModel\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"code\",\n        \"message\"\n      ],\n      \"properties\": {\n        \"code\": {\n          \"type\": \"integer\",\n          \"format\": \"int32\"\n        },\n        \"message\": {\n          \"type\": \"string\"\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "tests/fixtures/petstore.json",
    "content": "{\n  \"swagger\": \"2.0\",\n  \"info\": {\n    \"version\": \"1.0.0\",\n    \"title\": \"Swagger Petstore\",\n    \"contact\": {\n      \"name\": \"Swagger API Team\",\n      \"url\": \"http://Swagger.io\"\n    },\n    \"license\": {\n      \"name\": \"Creative Commons 4.0 International\",\n      \"url\": \"http://creativecommons.org/licenses/by/4.0/\"\n    }\n  },\n  \"host\": \"petstore.Swagger.io\",\n  \"basePath\": \"/api\",\n  \"schemes\": [\n    \"http\"\n  ],\n  \"paths\": {\n    \"/pets\": {\n      \"get\": {\n        \"tags\": [ \"Pet Operations\" ],\n        \"summary\": \"finds pets in the system\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"pet response\",\n            \"schema\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/Pet\"\n              }\n            },\n            \"headers\": {\n              \"x-expires\": {\n                \"type\": \"string\"\n              }\n            }\n          },\n          \"default\": {\n            \"description\": \"unexpected error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Error\"\n            }\n          }\n        }\n      }\n    }\n  },\n  \"definitions\": {\n    \"Pet\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"id\",\n        \"name\"\n      ],\n      \"properties\": {\n        \"id\": {\n          \"type\": \"integer\",\n          \"format\": \"int64\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"tag\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"Error\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"code\",\n        \"message\"\n      ],\n      \"properties\": {\n        \"code\": {\n          \"type\": \"integer\",\n          \"format\": \"int32\"\n        },\n        \"message\": {\n          \"type\": \"string\"\n        }\n      }\n    }\n  }\n}\n"
  }
]