diff --git a/CHANGELOG.md b/CHANGELOG.md index 7942c58..0e55563 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## Changelog +### Unreleased + +- Updated `mcp/sdk` to 0.5. + ### 5.0.3 - Added the missing PHP version requirement to `plugin.json` to reflect the plugin's actual runtime requirement. diff --git a/McpServerFactory.php b/McpServerFactory.php index 42930c8..222e06c 100644 --- a/McpServerFactory.php +++ b/McpServerFactory.php @@ -11,6 +11,9 @@ namespace Piwik\Plugins\McpServer; +use Matomo\Dependencies\McpServer\Mcp\Capability\Attribute\McpTool; +use Matomo\Dependencies\McpServer\Mcp\Capability\Discovery\DocBlockParser; +use Matomo\Dependencies\McpServer\Mcp\Capability\Discovery\SchemaGenerator; use Matomo\Dependencies\McpServer\Mcp\Capability\Registry; use Matomo\Dependencies\McpServer\Mcp\Capability\Registry\ReferenceHandler; use Matomo\Dependencies\McpServer\Mcp\Schema\ServerCapabilities; @@ -28,7 +31,18 @@ use Piwik\Plugins\McpServer\McpTools\ApiCallUpdate; use Piwik\Plugins\McpServer\McpTools\ApiGet; use Piwik\Plugins\McpServer\McpTools\ApiList; +use Piwik\Plugins\McpServer\McpTools\DimensionGet; +use Piwik\Plugins\McpServer\McpTools\DimensionList; +use Piwik\Plugins\McpServer\McpTools\GoalGet; +use Piwik\Plugins\McpServer\McpTools\GoalList; +use Piwik\Plugins\McpServer\McpTools\ReportList; +use Piwik\Plugins\McpServer\McpTools\ReportMetadata; use Piwik\Plugins\McpServer\McpTools\ReportProcessed; +use Piwik\Plugins\McpServer\McpTools\SegmentGet; +use Piwik\Plugins\McpServer\McpTools\SegmentList; +use Piwik\Plugins\McpServer\McpTools\SiteGet; +use Piwik\Plugins\McpServer\McpTools\SiteList; +use Piwik\Plugins\McpServer\McpTools\SiteSearch; use Piwik\Plugins\McpServer\Schemas\Api\ApiCallToolInputSchema; use Piwik\Plugins\McpServer\Schemas\Api\ApiCallToolOutputSchema; use Piwik\Plugins\McpServer\Schemas\Api\ApiGetToolInputSchema; @@ -70,7 +84,6 @@ public function createServer(): Server ->setRegistry($registry) ->setSession($this->sessionStore) ->setContainer($this->container) - ->setDiscovery(__DIR__, ['McpTools']) ->setCapabilities(new ServerCapabilities( tools: true, // Use null to avoid advertising listChanged capabilities we don't implement. @@ -84,6 +97,8 @@ public function createServer(): Server completions: false, )); + $this->registerAttributeTools($builder); + $builder->addTool( handler: [ReportProcessed::class, 'get'], name: ReportProcessed::TOOL_NAME, @@ -107,6 +122,7 @@ public function createServer(): Server $builder->addTool( [ApiGet::class, 'get'], ApiGet::TOOL_NAME, + null, "Use when: you already know the Matomo API method name and need its exact signature.\n" . "Purpose: return one authoritative API method summary with parameter metadata.\n" . "Do not use: for broad discovery across APIs; use " . ApiList::TOOL_NAME . ' instead.', @@ -124,6 +140,7 @@ public function createServer(): Server $builder->addTool( [ApiList::class, 'list'], ApiList::TOOL_NAME, + null, "Use when: you need discoverable Matomo API methods and parameter metadata.\n" . "Purpose: return paginated API method summaries aligned with Matomo API docs visibility.\n" . "Next: choose a method and map parameters for subsequent raw API tooling.", @@ -161,12 +178,68 @@ public function createServer(): Server return $builder->build(); } + private function registerAttributeTools(Builder $builder): void + { + $schemaGenerator = new SchemaGenerator(new DocBlockParser()); + + $tools = [ + [DimensionGet::class, 'get'], + [DimensionList::class, 'list'], + [GoalGet::class, 'get'], + [GoalList::class, 'list'], + [ReportList::class, 'list'], + [ReportMetadata::class, 'get'], + [SegmentGet::class, 'get'], + [SegmentList::class, 'list'], + [SiteGet::class, 'get'], + [SiteList::class, 'list'], + [SiteSearch::class, 'search'], + ]; + + foreach ($tools as [$className, $methodName]) { + $this->registerAttributeTool($builder, $schemaGenerator, $className, $methodName); + } + } + + /** + * @param class-string $className + */ + private function registerAttributeTool( + Builder $builder, + SchemaGenerator $schemaGenerator, + string $className, + string $methodName, + ): void { + $method = new \ReflectionMethod($className, $methodName); + $attribute = $method->getAttributes(McpTool::class, \ReflectionAttribute::IS_INSTANCEOF)[0] ?? null; + + if ($attribute === null) { + throw new \LogicException(sprintf('Missing McpTool attribute on %s::%s.', $className, $methodName)); + } + + /** @var McpTool $tool */ + $tool = $attribute->newInstance(); + + $builder->addTool( + [$className, $methodName], + $tool->name, + $tool->title, + $tool->description, + $tool->annotations, + $schemaGenerator->generate($method), + $tool->icons, + $tool->meta, + $schemaGenerator->generateOutputSchema($method), + ); + } + private function registerRawApiCallTools(Builder $builder, string $rawApiAccessMode): void { if (RawApiAccessMode::allowsCategory($rawApiAccessMode, RawApiAccessMode::READ)) { $builder->addTool( [ApiCallRead::class, 'call'], ApiCallRead::TOOL_NAME, + null, "Use when: you need to execute a known read-only Matomo API method directly.\n" . "Purpose: call one allowed read method and return its result plus the resolved method metadata.\n" . "Next: use " . ApiGet::TOOL_NAME . ' or ' . ApiList::TOOL_NAME @@ -188,6 +261,7 @@ private function registerRawApiCallTools(Builder $builder, string $rawApiAccessM $builder->addTool( [ApiCallCreate::class, 'call'], ApiCallCreate::TOOL_NAME, + null, "Use when: you need to execute a known create-style Matomo API method directly.\n" . "Purpose: call one allowed create method and return its result plus the" . " resolved method metadata.\n" @@ -210,6 +284,7 @@ private function registerRawApiCallTools(Builder $builder, string $rawApiAccessM $builder->addTool( [ApiCallUpdate::class, 'call'], ApiCallUpdate::TOOL_NAME, + null, "Use when: you need to execute a known update-style Matomo API method directly.\n" . "Purpose: call one allowed update method and return its result plus the" . " resolved method metadata.\n" @@ -232,6 +307,7 @@ private function registerRawApiCallTools(Builder $builder, string $rawApiAccessM $builder->addTool( [ApiCallDelete::class, 'call'], ApiCallDelete::TOOL_NAME, + null, "Use when: you need to execute a known delete-style Matomo API method directly.\n" . "Purpose: call one allowed delete method and return its result plus the" . " resolved method metadata.\n" @@ -254,6 +330,7 @@ private function registerRawApiCallTools(Builder $builder, string $rawApiAccessM $builder->addTool( [ApiCallFull::class, 'call'], ApiCallFull::TOOL_NAME, + null, "Use when: you need to execute a known Matomo API method directly and" . " it is not safely covered by one CRUD-specific tool.\n" . "Purpose: call one allowed full-access API method and return its result" diff --git a/composer.json b/composer.json index 47d32b4..223fd7d 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "require": { "php": "^8.1", - "mcp/sdk": "^0.4.0", + "mcp/sdk": "^0.5.0", "nyholm/psr7": "^1.8", "nyholm/psr7-server": "^1.1" }, diff --git a/composer.lock b/composer.lock index 10ecc2a..d16e05d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "563590b2e82acd6e9ca081e3284ab097", + "content-hash": "97bf171892194fa2fb3ba397e154598d", "packages": [ { "name": "doctrine/deprecations", @@ -56,16 +56,16 @@ }, { "name": "mcp/sdk", - "version": "v0.4.0", + "version": "v0.5.0", "source": { "type": "git", "url": "https://github.com/modelcontextprotocol/php-sdk.git", - "reference": "1f5f7e16a3af23dd43ec0a5c972d7aa8e8429024" + "reference": "fb2c8c2ee4ab2791239c5f534bb07bfb7589d4e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/modelcontextprotocol/php-sdk/zipball/1f5f7e16a3af23dd43ec0a5c972d7aa8e8429024", - "reference": "1f5f7e16a3af23dd43ec0a5c972d7aa8e8429024", + "url": "https://api.github.com/repos/modelcontextprotocol/php-sdk/zipball/fb2c8c2ee4ab2791239c5f534bb07bfb7589d4e8", + "reference": "fb2c8c2ee4ab2791239c5f534bb07bfb7589d4e8", "shasum": "" }, "require": { @@ -73,19 +73,22 @@ "opis/json-schema": "^2.4", "php": "^8.1", "php-http/discovery": "^1.20", - "phpdocumentor/reflection-docblock": "^5.6", + "phpdocumentor/reflection-docblock": "^5.6 || ^6.0", "psr/clock": "^1.0", "psr/container": "^1.0 || ^2.0", "psr/event-dispatcher": "^1.0", + "psr/http-client": "^1.0", "psr/http-factory": "^1.1", "psr/http-message": "^1.1 || ^2.0", "psr/http-server-handler": "^1.0", "psr/http-server-middleware": "^1.0", "psr/log": "^1.0 || ^2.0 || ^3.0", - "symfony/finder": "^5.4 || ^6.4 || ^7.3 || ^8.0", "symfony/uid": "^5.4 || ^6.4 || ^7.3 || ^8.0" }, "require-dev": { + "composer/semver": "^3.0", + "ext-openssl": "*", + "firebase/php-jwt": "^6.10 || ^7.0", "laminas/laminas-httphandlerrunner": "^2.12", "nyholm/psr7": "^1.8", "nyholm/psr7-server": "^1.1", @@ -97,8 +100,13 @@ "psr/simple-cache": "^2.0 || ^3.0", "symfony/cache": "^5.4 || ^6.4 || ^7.3 || ^8.0", "symfony/console": "^5.4 || ^6.4 || ^7.3 || ^8.0", + "symfony/finder": "^5.4 || ^6.4 || ^7.3 || ^8.0", + "symfony/http-client": "^5.4 || ^6.4 || ^7.3 || ^8.0", "symfony/process": "^5.4 || ^6.4 || ^7.3 || ^8.0" }, + "suggest": { + "symfony/finder": "Required for file-based discovery." + }, "type": "library", "autoload": { "psr-4": { @@ -126,9 +134,9 @@ "description": "Model Context Protocol SDK for Client and Server applications in PHP", "support": { "issues": "https://github.com/modelcontextprotocol/php-sdk/issues", - "source": "https://github.com/modelcontextprotocol/php-sdk/tree/v0.4.0" + "source": "https://github.com/modelcontextprotocol/php-sdk/tree/v0.5.0" }, - "time": "2026-02-23T21:42:54+00:00" + "time": "2026-04-26T13:37:40+00:00" }, { "name": "nyholm/psr7", @@ -598,16 +606,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.6.6", + "version": "6.0.3", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "5cee1d3dfc2d2aa6599834520911d246f656bcb8" + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/5cee1d3dfc2d2aa6599834520911d246f656bcb8", - "reference": "5cee1d3dfc2d2aa6599834520911d246f656bcb8", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/7bae67520aa9f5ecc506d646810bd40d9da54582", + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582", "shasum": "" }, "require": { @@ -615,8 +623,8 @@ "ext-filter": "*", "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.7", - "phpstan/phpdoc-parser": "^1.7|^2.0", + "phpdocumentor/type-resolver": "^2.0", + "phpstan/phpdoc-parser": "^2.0", "webmozart/assert": "^1.9.1 || ^2" }, "require-dev": { @@ -626,7 +634,8 @@ "phpstan/phpstan-mockery": "^1.1", "phpstan/phpstan-webmozart-assert": "^1.2", "phpunit/phpunit": "^9.5", - "psalm/phar": "^5.26" + "psalm/phar": "^5.26", + "shipmonk/dead-code-detector": "^0.5.1" }, "type": "library", "extra": { @@ -656,44 +665,44 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.6" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/6.0.3" }, - "time": "2025-12-22T21:13:58+00:00" + "time": "2026-03-18T20:49:53+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.12.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195" + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/92a98ada2b93d9b201a613cb5a33584dde25f195", - "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/327a05bbee54120d4786a0dc67aad30226ad4cf9", + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9", "shasum": "" }, "require": { "doctrine/deprecations": "^1.0", - "php": "^7.3 || ^8.0", + "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.0", - "phpstan/phpdoc-parser": "^1.18|^2.0" + "phpstan/phpdoc-parser": "^2.0" }, "require-dev": { "ext-tokenizer": "*", "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "rector/rector": "^0.13.9", - "vimeo/psalm": "^4.25" + "psalm/phar": "^4" }, "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-1.x": "1.x-dev", + "dev-2.x": "2.x-dev" } }, "autoload": { @@ -714,9 +723,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.12.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/2.0.0" }, - "time": "2025-11-21T15:09:14+00:00" + "time": "2026-01-06T21:53:42+00:00" }, { "name": "phpstan/phpdoc-parser", @@ -813,6 +822,58 @@ }, "time": "2022-11-25T14:36:26+00:00" }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, { "name": "psr/http-factory", "version": "1.1.0", @@ -1034,86 +1095,18 @@ }, "time": "2023-04-11T06:14:47+00:00" }, - { - "name": "symfony/finder", - "version": "v6.4.34", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "9590e86be1d1c57bfbb16d0dd040345378c20896" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/9590e86be1d1c57bfbb16d0dd040345378c20896", - "reference": "9590e86be1d1c57bfbb16d0dd040345378c20896", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "symfony/filesystem": "^6.0|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Finds files and directories via an intuitive fluent interface", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/finder/tree/v6.4.34" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://github.com/nicolas-grekas", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2026-01-28T15:16:37+00:00" - }, { "name": "symfony/polyfill-uuid", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-uuid.git", - "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2" + "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/21533be36c24be3f4b1669c4725c7d1d2bab4ae2", - "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/26dfec253c4cf3e51b541b52ddf7e42cb0908e94", + "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94", "shasum": "" }, "require": { @@ -1163,7 +1156,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/polyfill-uuid/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.37.0" }, "funding": [ { @@ -1183,7 +1176,7 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/uid", diff --git a/tests/Unit/Server/Handler/Request/CompatibleCallToolHandlerTest.php b/tests/Unit/Server/Handler/Request/CompatibleCallToolHandlerTest.php index e28b500..a811625 100644 --- a/tests/Unit/Server/Handler/Request/CompatibleCallToolHandlerTest.php +++ b/tests/Unit/Server/Handler/Request/CompatibleCallToolHandlerTest.php @@ -91,7 +91,7 @@ public function testRejectsNonEmptyListApiParametersAgainstObjectOnlySchema(): v private function createTool(string $name): \Matomo\Dependencies\McpServer\Mcp\Schema\Tool { - return new \Matomo\Dependencies\McpServer\Mcp\Schema\Tool($name, [ + return new \Matomo\Dependencies\McpServer\Mcp\Schema\Tool($name, null, [ 'type' => 'object', 'properties' => [ 'idSite' => ['type' => 'integer'], diff --git a/tests/Unit/Server/Handler/Request/ObservedCallToolHandlerTest.php b/tests/Unit/Server/Handler/Request/ObservedCallToolHandlerTest.php index a26affc..c4a1e01 100644 --- a/tests/Unit/Server/Handler/Request/ObservedCallToolHandlerTest.php +++ b/tests/Unit/Server/Handler/Request/ObservedCallToolHandlerTest.php @@ -447,7 +447,7 @@ public function testFailureLogsAtDebugWhenVerboseConfigured(): void */ private function createTool(string $name, array $inputSchema): \Matomo\Dependencies\McpServer\Mcp\Schema\Tool { - return new \Matomo\Dependencies\McpServer\Mcp\Schema\Tool($name, $inputSchema, null, null); + return new \Matomo\Dependencies\McpServer\Mcp\Schema\Tool($name, null, $inputSchema, null, null); } private function createSession(string $uuid): Session diff --git a/vendor/autoload_original.php b/vendor/autoload_original.php index e33626e..130d5bc 100644 --- a/vendor/autoload_original.php +++ b/vendor/autoload_original.php @@ -22,4 +22,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit563590b2e82acd6e9ca081e3284ab097::getLoader(); +return ComposerAutoloaderInit97bf171892194fa2fb3ba397e154598d::getLoader(); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 5245a75..032b209 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -10,9 +10,9 @@ 'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'), 'Symfony\\Polyfill\\Uuid\\' => array($vendorDir . '/symfony/polyfill-uuid'), 'Symfony\\Component\\Uid\\' => array($vendorDir . '/symfony/uid'), - 'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'), 'Psr\\Http\\Server\\' => array($vendorDir . '/psr/http-server-handler/src', $vendorDir . '/psr/http-server-middleware/src'), 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'), + 'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'), 'Psr\\Clock\\' => array($vendorDir . '/psr/clock/src'), 'PHPStan\\PhpDocParser\\' => array($vendorDir . '/phpstan/phpdoc-parser/src'), 'Opis\\Uri\\' => array($vendorDir . '/opis/uri/src'), diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 4a0f3d7..bb7ff16 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit563590b2e82acd6e9ca081e3284ab097 +class ComposerAutoloaderInit97bf171892194fa2fb3ba397e154598d { private static $loader; @@ -22,16 +22,16 @@ public static function getLoader() return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit563590b2e82acd6e9ca081e3284ab097', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit97bf171892194fa2fb3ba397e154598d', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); - spl_autoload_unregister(array('ComposerAutoloaderInit563590b2e82acd6e9ca081e3284ab097', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit97bf171892194fa2fb3ba397e154598d', 'loadClassLoader')); require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit563590b2e82acd6e9ca081e3284ab097::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit97bf171892194fa2fb3ba397e154598d::getInitializer($loader)); $loader->register(true); - $filesToLoad = \Composer\Autoload\ComposerStaticInit563590b2e82acd6e9ca081e3284ab097::$files; + $filesToLoad = \Composer\Autoload\ComposerStaticInit97bf171892194fa2fb3ba397e154598d::$files; $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index af0d97d..3c2796f 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit563590b2e82acd6e9ca081e3284ab097 +class ComposerStaticInit97bf171892194fa2fb3ba397e154598d { public static $files = array( ); @@ -23,12 +23,12 @@ class ComposerStaticInit563590b2e82acd6e9ca081e3284ab097 array ( 'Symfony\\Polyfill\\Uuid\\' => 22, 'Symfony\\Component\\Uid\\' => 22, - 'Symfony\\Component\\Finder\\' => 25, ), 'P' => array ( 'Psr\\Http\\Server\\' => 16, 'Psr\\Http\\Message\\' => 17, + 'Psr\\Http\\Client\\' => 16, 'Psr\\Clock\\' => 10, 'PHPStan\\PhpDocParser\\' => 21, ), @@ -76,10 +76,6 @@ class ComposerStaticInit563590b2e82acd6e9ca081e3284ab097 array ( 0 => __DIR__ . '/..' . '/symfony/uid', ), - 'Symfony\\Component\\Finder\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/finder', - ), 'Psr\\Http\\Server\\' => array ( 0 => __DIR__ . '/..' . '/psr/http-server-handler/src', @@ -90,6 +86,10 @@ class ComposerStaticInit563590b2e82acd6e9ca081e3284ab097 0 => __DIR__ . '/..' . '/psr/http-factory/src', 1 => __DIR__ . '/..' . '/psr/http-message/src', ), + 'Psr\\Http\\Client\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/http-client/src', + ), 'Psr\\Clock\\' => array ( 0 => __DIR__ . '/..' . '/psr/clock/src', @@ -139,9 +139,9 @@ class ComposerStaticInit563590b2e82acd6e9ca081e3284ab097 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit563590b2e82acd6e9ca081e3284ab097::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit563590b2e82acd6e9ca081e3284ab097::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit563590b2e82acd6e9ca081e3284ab097::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit97bf171892194fa2fb3ba397e154598d::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit97bf171892194fa2fb3ba397e154598d::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit97bf171892194fa2fb3ba397e154598d::$classMap; }, null, ClassLoader::class); } diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 980f9cc..2ba370a 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -53,17 +53,17 @@ }, { "name": "mcp/sdk", - "version": "v0.4.0", - "version_normalized": "0.4.0.0", + "version": "v0.5.0", + "version_normalized": "0.5.0.0", "source": { "type": "git", "url": "https://github.com/modelcontextprotocol/php-sdk.git", - "reference": "1f5f7e16a3af23dd43ec0a5c972d7aa8e8429024" + "reference": "fb2c8c2ee4ab2791239c5f534bb07bfb7589d4e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/modelcontextprotocol/php-sdk/zipball/1f5f7e16a3af23dd43ec0a5c972d7aa8e8429024", - "reference": "1f5f7e16a3af23dd43ec0a5c972d7aa8e8429024", + "url": "https://api.github.com/repos/modelcontextprotocol/php-sdk/zipball/fb2c8c2ee4ab2791239c5f534bb07bfb7589d4e8", + "reference": "fb2c8c2ee4ab2791239c5f534bb07bfb7589d4e8", "shasum": "" }, "require": { @@ -71,19 +71,22 @@ "opis/json-schema": "^2.4", "php": "^8.1", "php-http/discovery": "^1.20", - "phpdocumentor/reflection-docblock": "^5.6", + "phpdocumentor/reflection-docblock": "^5.6 || ^6.0", "psr/clock": "^1.0", "psr/container": "^1.0 || ^2.0", "psr/event-dispatcher": "^1.0", + "psr/http-client": "^1.0", "psr/http-factory": "^1.1", "psr/http-message": "^1.1 || ^2.0", "psr/http-server-handler": "^1.0", "psr/http-server-middleware": "^1.0", "psr/log": "^1.0 || ^2.0 || ^3.0", - "symfony/finder": "^5.4 || ^6.4 || ^7.3 || ^8.0", "symfony/uid": "^5.4 || ^6.4 || ^7.3 || ^8.0" }, "require-dev": { + "composer/semver": "^3.0", + "ext-openssl": "*", + "firebase/php-jwt": "^6.10 || ^7.0", "laminas/laminas-httphandlerrunner": "^2.12", "nyholm/psr7": "^1.8", "nyholm/psr7-server": "^1.1", @@ -95,9 +98,14 @@ "psr/simple-cache": "^2.0 || ^3.0", "symfony/cache": "^5.4 || ^6.4 || ^7.3 || ^8.0", "symfony/console": "^5.4 || ^6.4 || ^7.3 || ^8.0", + "symfony/finder": "^5.4 || ^6.4 || ^7.3 || ^8.0", + "symfony/http-client": "^5.4 || ^6.4 || ^7.3 || ^8.0", "symfony/process": "^5.4 || ^6.4 || ^7.3 || ^8.0" }, - "time": "2026-02-23T21:42:54+00:00", + "suggest": { + "symfony/finder": "Required for file-based discovery." + }, + "time": "2026-04-26T13:37:40+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -126,7 +134,7 @@ "description": "Model Context Protocol SDK for Client and Server applications in PHP", "support": { "issues": "https://github.com/modelcontextprotocol/php-sdk/issues", - "source": "https://github.com/modelcontextprotocol/php-sdk/tree/v0.4.0" + "source": "https://github.com/modelcontextprotocol/php-sdk/tree/v0.5.0" }, "install-path": "../mcp/sdk" }, @@ -619,17 +627,17 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.6.6", - "version_normalized": "5.6.6.0", + "version": "6.0.3", + "version_normalized": "6.0.3.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "5cee1d3dfc2d2aa6599834520911d246f656bcb8" + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/5cee1d3dfc2d2aa6599834520911d246f656bcb8", - "reference": "5cee1d3dfc2d2aa6599834520911d246f656bcb8", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/7bae67520aa9f5ecc506d646810bd40d9da54582", + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582", "shasum": "" }, "require": { @@ -637,8 +645,8 @@ "ext-filter": "*", "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.7", - "phpstan/phpdoc-parser": "^1.7|^2.0", + "phpdocumentor/type-resolver": "^2.0", + "phpstan/phpdoc-parser": "^2.0", "webmozart/assert": "^1.9.1 || ^2" }, "require-dev": { @@ -648,9 +656,10 @@ "phpstan/phpstan-mockery": "^1.1", "phpstan/phpstan-webmozart-assert": "^1.2", "phpunit/phpunit": "^9.5", - "psalm/phar": "^5.26" + "psalm/phar": "^5.26", + "shipmonk/dead-code-detector": "^0.5.1" }, - "time": "2025-12-22T21:13:58+00:00", + "time": "2026-03-18T20:49:53+00:00", "type": "library", "extra": { "branch-alias": { @@ -680,46 +689,46 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.6" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/6.0.3" }, "install-path": "../phpdocumentor/reflection-docblock" }, { "name": "phpdocumentor/type-resolver", - "version": "1.12.0", - "version_normalized": "1.12.0.0", + "version": "2.0.0", + "version_normalized": "2.0.0.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195" + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/92a98ada2b93d9b201a613cb5a33584dde25f195", - "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/327a05bbee54120d4786a0dc67aad30226ad4cf9", + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9", "shasum": "" }, "require": { "doctrine/deprecations": "^1.0", - "php": "^7.3 || ^8.0", + "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.0", - "phpstan/phpdoc-parser": "^1.18|^2.0" + "phpstan/phpdoc-parser": "^2.0" }, "require-dev": { "ext-tokenizer": "*", "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "rector/rector": "^0.13.9", - "vimeo/psalm": "^4.25" + "psalm/phar": "^4" }, - "time": "2025-11-21T15:09:14+00:00", + "time": "2026-01-06T21:53:42+00:00", "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-1.x": "1.x-dev", + "dev-2.x": "2.x-dev" } }, "installation-source": "dist", @@ -741,7 +750,7 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.12.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/2.0.0" }, "install-path": "../phpdocumentor/type-resolver" }, @@ -846,6 +855,61 @@ }, "install-path": "../psr/clock" }, + { + "name": "psr/http-client", + "version": "1.0.3", + "version_normalized": "1.0.3.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "time": "2023-09-23T14:17:50+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "install-path": "../psr/http-client" + }, { "name": "psr/http-factory", "version": "1.1.0", @@ -1079,90 +1143,19 @@ }, "install-path": "../psr/http-server-middleware" }, - { - "name": "symfony/finder", - "version": "v6.4.34", - "version_normalized": "6.4.34.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "9590e86be1d1c57bfbb16d0dd040345378c20896" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/9590e86be1d1c57bfbb16d0dd040345378c20896", - "reference": "9590e86be1d1c57bfbb16d0dd040345378c20896", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "symfony/filesystem": "^6.0|^7.0" - }, - "time": "2026-01-28T15:16:37+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Finds files and directories via an intuitive fluent interface", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/finder/tree/v6.4.34" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://github.com/nicolas-grekas", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "install-path": "../symfony/finder" - }, { "name": "symfony/polyfill-uuid", - "version": "v1.33.0", - "version_normalized": "1.33.0.0", + "version": "v1.37.0", + "version_normalized": "1.37.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-uuid.git", - "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2" + "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/21533be36c24be3f4b1669c4725c7d1d2bab4ae2", - "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/26dfec253c4cf3e51b541b52ddf7e42cb0908e94", + "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94", "shasum": "" }, "require": { @@ -1174,7 +1167,7 @@ "suggest": { "ext-uuid": "For best performance" }, - "time": "2024-09-09T11:45:10+00:00", + "time": "2026-04-10T16:19:22+00:00", "type": "library", "extra": { "thanks": { @@ -1214,7 +1207,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/polyfill-uuid/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.37.0" }, "funding": [ { diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 9a7467e..ad4efec 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => '__root__', 'pretty_version' => 'dev-5.x-dev', 'version' => 'dev-5.x-dev', - 'reference' => '91c3c82b14dfadf0c740d712352214640aa0df5a', + 'reference' => 'fc489aad9294e10a6b8173d671044079bd1cdf2e', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -13,7 +13,7 @@ '__root__' => array( 'pretty_version' => 'dev-5.x-dev', 'version' => 'dev-5.x-dev', - 'reference' => '91c3c82b14dfadf0c740d712352214640aa0df5a', + 'reference' => 'fc489aad9294e10a6b8173d671044079bd1cdf2e', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -29,9 +29,9 @@ 'dev_requirement' => false, ), 'mcp/sdk' => array( - 'pretty_version' => 'v0.4.0', - 'version' => '0.4.0.0', - 'reference' => '1f5f7e16a3af23dd43ec0a5c972d7aa8e8429024', + 'pretty_version' => 'v0.5.0', + 'version' => '0.5.0.0', + 'reference' => 'fb2c8c2ee4ab2791239c5f534bb07bfb7589d4e8', 'type' => 'library', 'install_path' => __DIR__ . '/../mcp/sdk', 'aliases' => array(), @@ -119,18 +119,18 @@ 'dev_requirement' => false, ), 'phpdocumentor/reflection-docblock' => array( - 'pretty_version' => '5.6.6', - 'version' => '5.6.6.0', - 'reference' => '5cee1d3dfc2d2aa6599834520911d246f656bcb8', + 'pretty_version' => '6.0.3', + 'version' => '6.0.3.0', + 'reference' => '7bae67520aa9f5ecc506d646810bd40d9da54582', 'type' => 'library', 'install_path' => __DIR__ . '/../phpdocumentor/reflection-docblock', 'aliases' => array(), 'dev_requirement' => false, ), 'phpdocumentor/type-resolver' => array( - 'pretty_version' => '1.12.0', - 'version' => '1.12.0.0', - 'reference' => '92a98ada2b93d9b201a613cb5a33584dde25f195', + 'pretty_version' => '2.0.0', + 'version' => '2.0.0.0', + 'reference' => '327a05bbee54120d4786a0dc67aad30226ad4cf9', 'type' => 'library', 'install_path' => __DIR__ . '/../phpdocumentor/type-resolver', 'aliases' => array(), @@ -166,6 +166,15 @@ 0 => '*', ), ), + 'psr/http-client' => array( + 'pretty_version' => '1.0.3', + 'version' => '1.0.3.0', + 'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-client', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'psr/http-client-implementation' => array( 'dev_requirement' => false, 'provided' => array( @@ -228,19 +237,10 @@ 0 => '*', ), ), - 'symfony/finder' => array( - 'pretty_version' => 'v6.4.34', - 'version' => '6.4.34.0', - 'reference' => '9590e86be1d1c57bfbb16d0dd040345378c20896', - 'type' => 'library', - 'install_path' => __DIR__ . '/../symfony/finder', - 'aliases' => array(), - 'dev_requirement' => false, - ), 'symfony/polyfill-uuid' => array( - 'pretty_version' => 'v1.33.0', - 'version' => '1.33.0.0', - 'reference' => '21533be36c24be3f4b1669c4725c7d1d2bab4ae2', + 'pretty_version' => 'v1.37.0', + 'version' => '1.37.0.0', + 'reference' => '26dfec253c4cf3e51b541b52ddf7e42cb0908e94', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-uuid', 'aliases' => array(), diff --git a/vendor/prefixed/mcp/sdk/CHANGELOG.md b/vendor/prefixed/mcp/sdk/CHANGELOG.md index cb7b101..67ae392 100644 --- a/vendor/prefixed/mcp/sdk/CHANGELOG.md +++ b/vendor/prefixed/mcp/sdk/CHANGELOG.md @@ -2,11 +2,29 @@ All notable changes to `mcp/sdk` will be documented in this file. +0.5.0 +----- + +* Add built-in authentication middleware for HTTP transport using OAuth +* Add client component for building MCP clients +* Add `Builder::setReferenceHandler()` to allow custom `ReferenceHandlerInterface` implementations (e.g. authorization decorators) +* Add elicitation enum schema types per SEP-1330: `TitledEnumSchemaDefinition`, `MultiSelectEnumSchemaDefinition`, `TitledMultiSelectEnumSchemaDefinition` +* [BC break] Make Symfony Finder component optional. Users would need to install `symfony/finder` now themselves +* Add `LenientOidcDiscoveryMetadataPolicy` for identity providers that omit `code_challenge_methods_supported` (e.g. FusionAuth, Microsoft Entra ID) +* Add OAuth 2.0 Dynamic Client Registration middleware (RFC 7591) +* Add optional `title` field to `Prompt` and `McpPrompt` for MCP spec compliance +* [BC Break] `Builder::addPrompt()` signature changed — `$title` parameter added between `$name` and `$description`. Callers using positional arguments for `$description` must switch to named arguments. +* Add optional `title` field to `Tool` and `McpTool` for MCP spec compliance +* [BC Break] `Tool::__construct()` signature changed — `$title` parameter added between `$name` and `$inputSchema`. Callers using positional arguments must switch to named arguments or pass `null` for `$title`. +* [BC Break] `McpTool` attribute signature changed — `$title` parameter added between `$name` and `$description`. Callers using positional arguments for `$description` must switch to named arguments. +* [BC Break] `Builder::addTool()` signature changed — `$title` parameter added between `$name` and `$description`. Callers using positional arguments for `$description` must switch to named arguments. + 0.4.0 ----- * Rename `Mcp\Server\Session\Psr16StoreSession` to `Mcp\Server\Session\Psr16SessionStore` * Add missing handlers for resource subscribe/unsubscribe and persist subscriptions via session +* Introduce `SessionManager` to encapsulate session handling (replaces `SessionFactory`) and move garbage collection logic from `Protocol`. 0.3.0 ----- diff --git a/vendor/prefixed/mcp/sdk/README.md b/vendor/prefixed/mcp/sdk/README.md index e45e495..37335b1 100644 --- a/vendor/prefixed/mcp/sdk/README.md +++ b/vendor/prefixed/mcp/sdk/README.md @@ -3,25 +3,25 @@ The official PHP SDK for Model Context Protocol (MCP). It provides a framework-agnostic API for implementing MCP servers and clients in PHP. -> [!IMPORTANT] -> This SDK is currently in active development with ongoing refinement of its architecture and features. While -> functional, the API may experience changes as we work toward stabilization. -> -> If you want to help us stabilize the SDK, please see the [issue tracker](https://github.com/modelcontextprotocol/php-sdk/issues). - This project represents a collaboration between [the PHP Foundation](https://thephp.foundation/) and the [Symfony project](https://symfony.com/). It adopts development practices and standards from the Symfony project, including [Coding Standards](https://symfony.com/doc/current/contributing/code/standards.html) and the [Backward Compatibility Promise](https://symfony.com/doc/current/contributing/code/bc.html). -Until the first major release, this SDK is considered [experimental](https://symfony.com/doc/current/contributing/code/experimental.html). +Until the first major release, this SDK is considered [experimental](https://symfony.com/doc/current/contributing/code/experimental.html), please see the [roadmap](./ROADMAP.md) for +planned next steps and features. -## Roadmap +## Table of Contents -**Features** -- [ ] Stabilize server component with all needed handlers and functional tests -- [ ] Extend documentation, including integration guides for popular frameworks -- [ ] Implement Client component -- [ ] Support multiple schema versions +- [Installation](#installation) +- [Overview](#overview) +- [Server SDK](#server-sdk) +- [Client SDK](#client-sdk) +- [Documentation](#documentation) +- [External Resources](#external-resources) +- [PHP Libraries Using the MCP SDK](#php-libraries-using-the-mcp-sdk) +- [Contributing](#contributing) +- [Credits](#credits) +- [License](#license) ## Installation @@ -29,196 +29,124 @@ Until the first major release, this SDK is considered [experimental](https://sym composer require mcp/sdk ``` -## Quick Start +## Overview -This example demonstrates the most common usage pattern - a STDIO server using attribute discovery. +The MCP PHP SDK provides both **server** and **client** implementations for the Model Context Protocol, enabling you to: -### 1. Define Your MCP Elements +- **Build MCP Servers**: Expose your PHP application's functionality (tools, resources, prompts) to AI agents +- **Build MCP Clients**: Connect to and interact with MCP servers from your PHP applications -Create a class with MCP capabilities using attributes: +## Server SDK -```php - $a + $b, - 'subtract' => $a - $b, - 'multiply' => $a * $b, - 'divide' => $b != 0 ? $a / $b : 'Error: Division by zero', - default => 'Error: Unknown operation' - }; - } - - #[McpResource( - uri: 'config://calculator/settings', - name: 'calculator_config', - mimeType: 'application/json' - )] + #[McpResource(uri: 'config://calculator/settings')] public function getSettings(): array { - return ['precision' => 2, 'allow_negative' => true]; + return ['precision' => 2]; } } -``` - -### 2. Create the Server Script - -Create your MCP server: - -```php -#!/usr/bin/env php -setServerInfo('Calculator Server', '1.0.0') - ->setDiscovery(__DIR__, ['.']) + ->setDiscovery(__DIR__, ['.']) // Auto-discover attributes ->build(); $transport = new StdioTransport(); - $server->run($transport); ``` -### 3. Configure Your MCP Client - -Add to your client configuration (e.g., Claude Desktop's `mcp.json`): - -```json -{ - "mcpServers": { - "php-calculator": { - "command": "php", - "args": ["/absolute/path/to/your/server.php"] - } - } -} -``` - -### 4. Test Your Server +### Server Capabilities -```bash -# Test with MCP Inspector -npx @modelcontextprotocol/inspector php /path/to/server.php +- **Tools**: Executable functions that AI agents can call +- **Resources**: Data sources that can be read (files, configs, databases) +- **Resource Templates**: Dynamic resources with URI parameters +- **Prompts**: Pre-defined templates for AI interactions +- **Server-Initiated Communication**: Elicitations, sampling, logging, progress notifications -# Your AI assistant can now call: -# - add: Add two integers -# - calculate: Perform arithmetic operations -# - Read config://calculator/settings resource -``` - -## Key Features - -### Attribute-Based Discovery +### Registration Methods -Define MCP elements using PHP attributes with automatic discovery: +There are multiple ways to register your MCP capabilities—choose the approach that best fits your application's architecture: +**1. Attribute-Based Discovery** — Define capabilities using PHP attributes for automatic discovery: ```php -// Tool with automatic name and description from method #[McpTool] public function generateReport(): string { /* ... */ } -// Tool with custom name -#[McpTool(name: 'custom_name')] -public function myMethod(): string { /* ... */ } - -// Resource with URI and metadata -#[McpResource(uri: 'config://app/settings', mimeType: 'application/json')] +#[McpResource(uri: 'config://app/settings')] public function getConfig(): array { /* ... */ } ``` -### Manual Registration - -Register capabilities programmatically: +**2. Manual Registration** — Register capabilities programmatically without attributes: +```php +$server = Server::builder() + ->addTool([Calculator::class, 'add'], 'add_numbers') + ->addResource([Config::class, 'get'], 'config://app') + ->build(); +``` +**3. Hybrid Approach** — Combine both methods for maximum flexibility: ```php $server = Server::builder() - ->addTool([MyClass::class, 'myMethod'], 'tool_name') - ->addResource([MyClass::class, 'getData'], 'data://config') + ->setDiscovery(__DIR__, ['.']) + ->addTool([ExternalService::class, 'process'], 'external') ->build(); ``` -### Multiple Transport Options +### Transports + +Choose the transport that matches your deployment environment: -**STDIO Transport** (Command-line integration): +**1. STDIO Transport** — For command-line integration and local processes: ```php $transport = new StdioTransport(); $server->run($transport); ``` -**HTTP Transport** (Web-based communication): +**2. HTTP Transport** — For web-based servers and distributed systems: ```php $transport = new StreamableHttpTransport($request, $responseFactory, $streamFactory); $response = $server->run($transport); -// Handle $response in your web application ``` ### Session Management -By default, the SDK uses in-memory sessions. You can configure different session stores: +Configure session storage to maintain state between requests. Choose the backend that fits your infrastructure: +**In-Memory** (default, suitable for STDIO): ```php -use Mcp\Server\Session\FileSessionStore; -use Mcp\Server\Session\InMemorySessionStore; -use Mcp\Server\Session\Psr16SessionStore; -use Symfony\Component\Cache\Psr16Cache; -use Symfony\Component\Cache\Adapter\RedisAdapter; - -// Use default in-memory sessions with custom TTL $server = Server::builder() ->setSession(ttl: 7200) // 2 hours ->build(); +``` -// Override with file-based storage +**File-Based** (suitable for single-server HTTP deployments): +```php $server = Server::builder() ->setSession(new FileSessionStore(__DIR__ . '/sessions')) ->build(); +``` -// Override with in-memory storage and custom TTL -$server = Server::builder() - ->setSession(new InMemorySessionStore(3600)) - ->build(); - -// Override with PSR-16 cache-based storage -// Requires psr/simple-cache and symfony/cache (or any other PSR-16 implementation) -// composer require psr/simple-cache symfony/cache -$redisAdapter = new RedisAdapter( - RedisAdapter::createConnection('redis://localhost:6379'), - 'mcp_sessions' -); - +**PSR-16 Cache** (for example with Redis for scaled deployments): +```php $server = Server::builder() ->setSession(new Psr16SessionStore( cache: new Psr16Cache($redisAdapter), @@ -228,60 +156,141 @@ $server = Server::builder() ->build(); ``` -### Discovery Caching +[→ Server Documentation](docs/server-builder.md) + +## Client SDK -Use any PSR-16 cache implementation to cache discovery results and avoid running discovery on every server start: +Connect to MCP servers from your PHP applications to access their tools, resources, and prompts. + +### Quick Start ```php -use Symfony\Component\Cache\Adapter\FilesystemAdapter; -use Symfony\Component\Cache\Psr16Cache; +use Mcp\Client; +use Mcp\Client\Transport\StdioTransport; + +// Build the client +$client = Client::builder() + ->setClientInfo('My Application', '1.0.0') + ->setInitTimeout(30) + ->setRequestTimeout(120) + ->build(); -$cache = new Psr16Cache(new FilesystemAdapter('mcp-discovery')); +// Connect to a server +$transport = new StdioTransport( + command: 'php', + args: ['/path/to/server.php'], +); -$server = Server::builder() - ->setDiscovery( - basePath: __DIR__, - scanDirs: ['.', 'src'], // Default: ['.', 'src'] - excludeDirs: ['vendor'], // Default: ['vendor', 'node_modules'] - cache: $cache - ) +$client->connect($transport); + +// Discover and use capabilities +$tools = $client->listTools(); +$result = $client->callTool('add', ['a' => 5, 'b' => 3]); + +$resources = $client->listResources(); +$content = $client->readResource('config://calculator/settings'); + +$client->disconnect(); +``` + +### Client Capabilities + +- **Tool Calling**: List and execute tools from any MCP server +- **Resource Access**: Read static and dynamic resources +- **Prompt Management**: List and retrieve prompt templates +- **Completion Support**: Request argument completion suggestions + +### Advanced Features + +- **Progress Tracking**: Real-time progress during long operations +```php +$result = $client->callTool( + name: 'process_data', + arguments: ['dataset' => 'large_file.csv'], + onProgress: function (float $progress, ?float $total, ?string $message) { + echo "Progress: {$progress}/{$total} - {$message}\n"; + } +); +``` + +- **Sampling Support**: Handle server LLM sampling requests +```php +$samplingHandler = new SamplingRequestHandler($myCallback); +$client = Client::builder() + ->setCapabilities(new ClientCapabilities(sampling: true)) + ->addRequestHandler($samplingHandler) + ->build(); +``` + +- **Logging Notifications**: Receive server log messages +```php +$loggingHandler = new LoggingNotificationHandler($myCallback); +$client = Client::builder() + ->addNotificationHandler($loggingHandler) ->build(); ``` +### Transports + +Connect to MCP servers using the transport that matches your setup: + +**1. STDIO Transport** — Connect to local server processes: +```php +$transport = new StdioTransport( + command: 'php', + args: ['/path/to/server.php'], +); + +$client->connect($transport); +``` + +**2. HTTP Transport** — Connect to remote or web-based servers: +```php +$transport = new HttpTransport('http://localhost:8000'); + +$client->connect($transport); +``` + +[→ Client Documentation](docs/client.md) + ## Documentation -**Core Concepts:** -- [Server Builder](docs/server-builder.md) - Complete ServerBuilder reference and configuration -- [Transports](docs/transports.md) - STDIO and HTTP transport setup and usage -- [MCP Elements](docs/mcp-elements.md) - Creating tools, resources, and prompts -- [Client Communication](docs/client-communication.md) - Communicating back to the client from server-side -- [Events](docs/events.md) - Hooking into server lifecycle with events +### Core Concepts + +- **[Server Builder](docs/server-builder.md)** — Complete ServerBuilder reference and configuration +- **[Client](docs/client.md)** — Client SDK for connecting to and communicating with MCP servers +- **[Transports](docs/transports.md)** — STDIO and HTTP transport setup and usage +- **[MCP Elements](docs/mcp-elements.md)** — Creating tools, resources, prompts, and templates +- **[Server-Client Communication](docs/server-client-communication.md)** — Sampling, logging, progress, and notifications +- **[Events](docs/events.md)** — Hooking into server lifecycle with events + +### Learning & Examples -**Learning:** -- [Examples](docs/examples.md) - Comprehensive example walkthroughs +- **[Examples](docs/examples.md)** — Comprehensive example walkthroughs for servers and clients +- **[ROADMAP.md](ROADMAP.md)** — Planned features and development roadmap -**External Resources:** -- [Model Context Protocol documentation](https://modelcontextprotocol.io) -- [Model Context Protocol specification](https://spec.modelcontextprotocol.io) -- [Officially supported servers](https://github.com/modelcontextprotocol/servers) +## External Resources + +- **[Model Context Protocol Documentation](https://modelcontextprotocol.io)** — Official MCP documentation +- **[Model Context Protocol Specification](https://spec.modelcontextprotocol.io)** — Protocol specification +- **[Officially Supported Servers](https://github.com/modelcontextprotocol/servers)** — Reference server implementations ## PHP Libraries Using the MCP SDK -* [pronskiy/mcp](https://github.com/pronskiy/mcp) - Additional DX layer -* [symfony/mcp-bundle](https://github.com/symfony/mcp-bundle) - Symfony integration bundle -* [josbeir/cakephp-synapse](https://github.com/josbeir/cakephp-synapse) - CakePHP integration plugin +- [pronskiy/mcp](https://github.com/pronskiy/mcp) — Additional developer experience layer +- [symfony/mcp-bundle](https://github.com/symfony/mcp-bundle) — Symfony integration bundle +- [josbeir/cakephp-synapse](https://github.com/josbeir/cakephp-synapse) — CakePHP integration plugin ## Contributing -We are passionate about supporting contributors of all levels of experience and would love to see you get involved in -the project. See the [contributing guide](CONTRIBUTING.md) to get started before you [report issues](https://github.com/modelcontextprotocol/php-sdk/issues) and [send pull requests](https://github.com/modelcontextprotocol/php-sdk/pulls). +We are passionate about supporting contributors of all levels of experience and would love to see you get involved in the project. + +See the [Contributing Guide](CONTRIBUTING.md) to get started before you [report issues](https://github.com/modelcontextprotocol/php-sdk/issues) and [send pull requests](https://github.com/modelcontextprotocol/php-sdk/pulls). ## Credits -The starting point for this SDK was the [PHP-MCP](https://github.com/php-mcp/server) project, initiated by -[Kyrian Obikwelu](https://github.com/CodeWithKyrian), and the [Symfony AI initiative](https://github.com/symfony/ai). We are grateful for the work -done by both projects and their contributors, which created a solid foundation for this SDK. +The starting point for this SDK was the [PHP-MCP](https://github.com/php-mcp/server) project, initiated by [Kyrian Obikwelu](https://github.com/CodeWithKyrian), and the [Symfony AI initiative](https://github.com/symfony/ai). We are grateful for the work done by both projects and their contributors, which created a solid foundation for this SDK. ## License -This project is licensed under the Apache License, Version 2.0 for new contributions, with existing code under the MIT License - see the [LICENSE](LICENSE) file for details. +This project is licensed under the Apache License, Version 2.0 for new contributions, with existing code under the MIT License — see the [LICENSE](LICENSE) file for details. diff --git a/vendor/prefixed/mcp/sdk/ROADMAP.md b/vendor/prefixed/mcp/sdk/ROADMAP.md new file mode 100644 index 0000000..03e4751 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/ROADMAP.md @@ -0,0 +1,15 @@ +# Roadmap + +This roadmap is a living document that outlines the planned features and improvements for our project. + +## Goals for the First Major Release + +- **Server** +- [ ] Implement full support for elicitations +- [ ] Implement OAuth2 authentication for server +- **Client** +- [x] Implement client-side support +- [x] Implement client examples and documentation +- **Schema** +- [ ] Implement schema generation based on TS or JSON Schema + diff --git a/vendor/prefixed/mcp/sdk/composer.json b/vendor/prefixed/mcp/sdk/composer.json index a94facd..aacc3d5 100644 --- a/vendor/prefixed/mcp/sdk/composer.json +++ b/vendor/prefixed/mcp/sdk/composer.json @@ -22,19 +22,25 @@ "ext-fileinfo": "*", "opis\/json-schema": "^2.4", "php-http\/discovery": "^1.20", - "phpdocumentor\/reflection-docblock": "^5.6", + "phpdocumentor\/reflection-docblock": "^5.6 || ^6.0", "psr\/clock": "^1.0", "psr\/container": "^1.0 || ^2.0", "psr\/event-dispatcher": "^1.0", + "psr\/http-client": "^1.0", "psr\/http-factory": "^1.1", "psr\/http-message": "^1.1 || ^2.0", "psr\/http-server-handler": "^1.0", "psr\/http-server-middleware": "^1.0", "psr\/log": "^1.0 || ^2.0 || ^3.0", - "symfony\/finder": "^5.4 || ^6.4 || ^7.3 || ^8.0", "symfony\/uid": "^5.4 || ^6.4 || ^7.3 || ^8.0" }, + "suggest": { + "symfony\/finder": "Required for file-based discovery." + }, "require-dev": { + "ext-openssl": "*", + "composer\/semver": "^3.0", + "firebase\/php-jwt": "^6.10 || ^7.0", "laminas\/laminas-httphandlerrunner": "^2.12", "nyholm\/psr7": "^1.8", "nyholm\/psr7-server": "^1.1", @@ -46,6 +52,8 @@ "psr\/simple-cache": "^2.0 || ^3.0", "symfony\/cache": "^5.4 || ^6.4 || ^7.3 || ^8.0", "symfony\/console": "^5.4 || ^6.4 || ^7.3 || ^8.0", + "symfony\/finder": "^5.4 || ^6.4 || ^7.3 || ^8.0", + "symfony\/http-client": "^5.4 || ^6.4 || ^7.3 || ^8.0", "symfony\/process": "^5.4 || ^6.4 || ^7.3 || ^8.0" }, "autoload": { @@ -68,6 +76,8 @@ "Matomo\\Dependencies\\McpServer\\Mcp\\Example\\Server\\DiscoveryUserProfile\\": "examples\/server\/discovery-userprofile\/", "Matomo\\Dependencies\\McpServer\\Mcp\\Example\\Server\\EnvVariables\\": "examples\/server\/env-variables\/", "Matomo\\Dependencies\\McpServer\\Mcp\\Example\\Server\\ExplicitRegistration\\": "examples\/server\/explicit-registration\/", + "Matomo\\Dependencies\\McpServer\\Mcp\\Example\\Server\\OAuthKeycloak\\": "examples\/server\/oauth-keycloak\/", + "Matomo\\Dependencies\\McpServer\\Mcp\\Example\\Server\\OAuthMicrosoft\\": "examples\/server\/oauth-microsoft\/", "Matomo\\Dependencies\\McpServer\\Mcp\\Example\\Server\\SchemaShowcase\\": "examples\/server\/schema-showcase\/", "Matomo\\Dependencies\\McpServer\\Mcp\\Tests\\": "tests\/" } diff --git a/vendor/prefixed/mcp/sdk/src/Capability/Attribute/McpPrompt.php b/vendor/prefixed/mcp/sdk/src/Capability/Attribute/McpPrompt.php index 9f49d26..68f7eae 100644 --- a/vendor/prefixed/mcp/sdk/src/Capability/Attribute/McpPrompt.php +++ b/vendor/prefixed/mcp/sdk/src/Capability/Attribute/McpPrompt.php @@ -18,15 +18,16 @@ * @author Kyrian Obikwelu */ #[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)] -final class McpPrompt +class McpPrompt { /** * @param ?string $name overrides the prompt name (defaults to method name) + * @param ?string $title Optional human-readable title for display in UI * @param ?string $description Optional description of the prompt. Defaults to method DocBlock summary. * @param ?Icon[] $icons Optional list of icon URLs representing the prompt * @param ?array $meta Optional metadata */ - public function __construct(public ?string $name = null, public ?string $description = null, public ?array $icons = null, public ?array $meta = null) + public function __construct(public ?string $name = null, public ?string $title = null, public ?string $description = null, public ?array $icons = null, public ?array $meta = null) { } } diff --git a/vendor/prefixed/mcp/sdk/src/Capability/Attribute/McpResource.php b/vendor/prefixed/mcp/sdk/src/Capability/Attribute/McpResource.php index aae84c3..d6a2fbd 100644 --- a/vendor/prefixed/mcp/sdk/src/Capability/Attribute/McpResource.php +++ b/vendor/prefixed/mcp/sdk/src/Capability/Attribute/McpResource.php @@ -19,7 +19,7 @@ * @author Kyrian Obikwelu */ #[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)] -final class McpResource +class McpResource { /** * @param string $uri The specific URI identifying this resource instance. Must be unique within the server. diff --git a/vendor/prefixed/mcp/sdk/src/Capability/Attribute/McpResourceTemplate.php b/vendor/prefixed/mcp/sdk/src/Capability/Attribute/McpResourceTemplate.php index 3d79dcc..03a7ddb 100644 --- a/vendor/prefixed/mcp/sdk/src/Capability/Attribute/McpResourceTemplate.php +++ b/vendor/prefixed/mcp/sdk/src/Capability/Attribute/McpResourceTemplate.php @@ -18,7 +18,7 @@ * @author Kyrian Obikwelu */ #[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)] -final class McpResourceTemplate +class McpResourceTemplate { /** * @param string $uriTemplate the URI template string (RFC 6570) diff --git a/vendor/prefixed/mcp/sdk/src/Capability/Attribute/McpTool.php b/vendor/prefixed/mcp/sdk/src/Capability/Attribute/McpTool.php index 56b96f6..e2f68ec 100644 --- a/vendor/prefixed/mcp/sdk/src/Capability/Attribute/McpTool.php +++ b/vendor/prefixed/mcp/sdk/src/Capability/Attribute/McpTool.php @@ -20,13 +20,14 @@ class McpTool { /** * @param string|null $name The name of the tool (defaults to the method name) + * @param string|null $title Optional human-readable title for display in UI * @param string|null $description The description of the tool (defaults to the DocBlock/inferred) * @param ToolAnnotations|null $annotations Optional annotations describing tool behavior * @param ?Icon[] $icons Optional list of icon URLs representing the tool * @param ?array $meta Optional metadata * @param array $outputSchema Optional JSON Schema object for defining the expected output structure */ - public function __construct(public ?string $name = null, public ?string $description = null, public ?ToolAnnotations $annotations = null, public ?array $icons = null, public ?array $meta = null, public ?array $outputSchema = null) + public function __construct(public ?string $name = null, public ?string $title = null, public ?string $description = null, public ?ToolAnnotations $annotations = null, public ?array $icons = null, public ?array $meta = null, public ?array $outputSchema = null) { } } diff --git a/vendor/prefixed/mcp/sdk/src/Capability/Attribute/Schema.php b/vendor/prefixed/mcp/sdk/src/Capability/Attribute/Schema.php index e0f979b..583744f 100644 --- a/vendor/prefixed/mcp/sdk/src/Capability/Attribute/Schema.php +++ b/vendor/prefixed/mcp/sdk/src/Capability/Attribute/Schema.php @@ -23,8 +23,8 @@ * definition?: array, * type?: string, * description?: string, - * enum?: array, - * gormat?: string, + * enum?: array, + * format?: string, * minLength?: int, * maxLength?: int, * pattern?: string, @@ -62,7 +62,7 @@ class Schema public ?string $description = null; public mixed $default = null; /** - * @var ?array + * @var ?array */ public ?array $enum = null; // list of allowed values @@ -104,26 +104,26 @@ class Schema public bool|array|null $additionalProperties = null; // true, false, or a schema array /** - * @param ?array $definition A complete JSON schema array. If provided, other parameters are ignored. - * @param ?string $type the JSON schema type - * @param ?string $description description of the element - * @param ?array $enum allowed enum values - * @param ?string $format String format (e.g., 'date-time', 'email'). - * @param ?int $minLength minimum length for strings - * @param ?int $maxLength maximum length for strings - * @param ?string $pattern regex pattern for strings - * @param int|float|null $minimum minimum value for numbers/integers - * @param int|float|null $maximum maximum value for numbers/integers - * @param ?bool $exclusiveMinimum exclusive minimum - * @param ?bool $exclusiveMaximum exclusive maximum - * @param int|float|null $multipleOf must be a multiple of this value - * @param ?array $items JSON Schema for items if type is 'array' - * @param ?int $minItems minimum items for an array - * @param ?int $maxItems maximum items for an array - * @param ?bool $uniqueItems whether array items must be unique - * @param ?array $properties Property definitions if type is 'object'. [name => schema_array]. - * @param ?array $required list of required properties for an object - * @param bool|array|null $additionalProperties policy for additional properties in an object + * @param ?array $definition A complete JSON schema array. If provided, other parameters are ignored. + * @param ?string $type the JSON schema type + * @param ?string $description description of the element + * @param ?array $enum allowed enum values + * @param ?string $format String format (e.g., 'date-time', 'email'). + * @param ?int $minLength minimum length for strings + * @param ?int $maxLength maximum length for strings + * @param ?string $pattern regex pattern for strings + * @param int|float|null $minimum minimum value for numbers/integers + * @param int|float|null $maximum maximum value for numbers/integers + * @param ?bool $exclusiveMinimum exclusive minimum + * @param ?bool $exclusiveMaximum exclusive maximum + * @param int|float|null $multipleOf must be a multiple of this value + * @param ?array $items JSON Schema for items if type is 'array' + * @param ?int $minItems minimum items for an array + * @param ?int $maxItems maximum items for an array + * @param ?bool $uniqueItems whether array items must be unique + * @param ?array $properties Property definitions if type is 'object'. [name => schema_array]. + * @param ?array $required list of required properties for an object + * @param bool|array|null $additionalProperties policy for additional properties in an object */ public function __construct(?array $definition = null, ?string $type = null, ?string $description = null, ?array $enum = null, ?string $format = null, ?int $minLength = null, ?int $maxLength = null, ?string $pattern = null, int|float|null $minimum = null, int|float|null $maximum = null, ?bool $exclusiveMinimum = null, ?bool $exclusiveMaximum = null, int|float|null $multipleOf = null, ?array $items = null, ?int $minItems = null, ?int $maxItems = null, ?bool $uniqueItems = null, ?array $properties = null, ?array $required = null, bool|array|null $additionalProperties = null) { diff --git a/vendor/prefixed/mcp/sdk/src/Capability/Discovery/Discoverer.php b/vendor/prefixed/mcp/sdk/src/Capability/Discovery/Discoverer.php index d29e704..515ed4e 100644 --- a/vendor/prefixed/mcp/sdk/src/Capability/Discovery/Discoverer.php +++ b/vendor/prefixed/mcp/sdk/src/Capability/Discovery/Discoverer.php @@ -23,6 +23,7 @@ use Matomo\Dependencies\McpServer\Mcp\Capability\Registry\ResourceTemplateReference; use Matomo\Dependencies\McpServer\Mcp\Capability\Registry\ToolReference; use Matomo\Dependencies\McpServer\Mcp\Exception\ExceptionInterface; +use Matomo\Dependencies\McpServer\Mcp\Exception\RuntimeException; use Matomo\Dependencies\McpServer\Mcp\Schema\Prompt; use Matomo\Dependencies\McpServer\Mcp\Schema\PromptArgument; use Matomo\Dependencies\McpServer\Mcp\Schema\Resource; @@ -30,8 +31,8 @@ use Matomo\Dependencies\McpServer\Mcp\Schema\Tool; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\Finder; -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\SplFileInfo; +use Symfony\Component\Finder\Finder; +use Symfony\Component\Finder\SplFileInfo; /** * @phpstan-type DiscoveredCount array{ * tools: int, @@ -48,6 +49,9 @@ final class Discoverer implements DiscovererInterface { public function __construct(private readonly LoggerInterface $logger = new NullLogger(), private ?DocBlockParser $docBlockParser = null, private ?SchemaGeneratorInterface $schemaGenerator = null) { + if (!class_exists(Finder::class)) { + throw new RuntimeException('File-based discovery requires symfony/finder. Run: composer require symfony/finder'); + } $this->docBlockParser = $docBlockParser ?? new DocBlockParser(logger: $this->logger); $this->schemaGenerator = $schemaGenerator ?? new SchemaGenerator($this->docBlockParser); } @@ -174,7 +178,7 @@ private function processMethod(\ReflectionMethod $method, array &$discoveredCoun $description = $instance->description ?? $this->docBlockParser->getDescription($docBlock) ?? null; $inputSchema = $this->schemaGenerator->generate($method); $outputSchema = $this->schemaGenerator->generateOutputSchema($method); - $tool = new Tool($name, $inputSchema, $description, $instance->annotations, $instance->icons, $instance->meta, $outputSchema); + $tool = new Tool(name: $name, title: $instance->title, inputSchema: $inputSchema, description: $description, annotations: $instance->annotations, icons: $instance->icons, meta: $instance->meta, outputSchema: $outputSchema); $tools[$name] = new ToolReference($tool, [$className, $methodName], \false); ++$discoveredCount['tools']; break; @@ -200,7 +204,7 @@ private function processMethod(\ReflectionMethod $method, array &$discoveredCoun $paramTag = $paramTags['$' . $param->getName()] ?? null; $arguments[] = new PromptArgument($param->getName(), $paramTag ? trim((string) $paramTag->getDescription()) : null, !$param->isOptional() && !$param->isDefaultValueAvailable()); } - $prompt = new Prompt($name, $description, $arguments, $instance->icons, $instance->meta); + $prompt = new Prompt($name, $instance->title, $description, $arguments, $instance->icons, $instance->meta); $completionProviders = $this->getCompletionProviders($method); $prompts[$name] = new PromptReference($prompt, [$className, $methodName], \false, $completionProviders); ++$discoveredCount['prompts']; diff --git a/vendor/prefixed/mcp/sdk/src/Capability/Discovery/SchemaGenerator.php b/vendor/prefixed/mcp/sdk/src/Capability/Discovery/SchemaGenerator.php index a100dad..be34c64 100644 --- a/vendor/prefixed/mcp/sdk/src/Capability/Discovery/SchemaGenerator.php +++ b/vendor/prefixed/mcp/sdk/src/Capability/Discovery/SchemaGenerator.php @@ -44,7 +44,7 @@ * type?: string|array, * description?: string, * default?: mixed, - * enum?: array, + * enum?: array, * items?: array, * } * @phpstan-type VariadicParameterSchema array{ diff --git a/vendor/prefixed/mcp/sdk/src/Capability/Registry/Loader/ArrayLoader.php b/vendor/prefixed/mcp/sdk/src/Capability/Registry/Loader/ArrayLoader.php index 78637a8..a8aeabc 100644 --- a/vendor/prefixed/mcp/sdk/src/Capability/Registry/Loader/ArrayLoader.php +++ b/vendor/prefixed/mcp/sdk/src/Capability/Registry/Loader/ArrayLoader.php @@ -43,6 +43,7 @@ final class ArrayLoader implements LoaderInterface * @param array{ * handler: Handler, * name: ?string, + * title: ?string, * description: ?string, * annotations: ?ToolAnnotations, * icons: ?Icon[], @@ -99,7 +100,7 @@ public function load(RegistryInterface $registry) : void $description = $data['description'] ?? $docBlockParser->getDescription($docBlock) ?? null; } $inputSchema = $data['inputSchema'] ?? $schemaGenerator->generate($reflection); - $tool = new Tool(name: $name, inputSchema: $inputSchema, description: $description, annotations: $data['annotations'] ?? null, icons: $data['icons'] ?? null, meta: $data['meta'] ?? null, outputSchema: $data['outputSchema'] ?? null); + $tool = new Tool(name: $name, title: $data['title'] ?? null, inputSchema: $inputSchema, description: $description, annotations: $data['annotations'] ?? null, icons: $data['icons'] ?? null, meta: $data['meta'] ?? null, outputSchema: $data['outputSchema'] ?? null); $registry->registerTool($tool, $data['handler'], \true); $handlerDesc = $this->getHandlerDescription($data['handler']); $this->logger->debug("Registered manual tool {$name} from handler {$handlerDesc}"); @@ -180,7 +181,7 @@ public function load(RegistryInterface $registry) : void $paramTag = $paramTags['$' . $param->getName()] ?? null; $arguments[] = new PromptArgument($param->getName(), $paramTag ? trim((string) $paramTag->getDescription()) : null, !$param->isOptional() && !$param->isDefaultValueAvailable()); } - $prompt = new Prompt(name: $name, description: $description, arguments: $arguments, icons: $data['icons'] ?? null, meta: $data['meta'] ?? null); + $prompt = new Prompt(name: $name, title: $data['title'] ?? null, description: $description, arguments: $arguments, icons: $data['icons'] ?? null, meta: $data['meta'] ?? null); $completionProviders = $this->getCompletionProviders($reflection); $registry->registerPrompt($prompt, $data['handler'], $completionProviders, \true); $handlerDesc = $this->getHandlerDescription($data['handler']); diff --git a/vendor/prefixed/mcp/sdk/src/Client.php b/vendor/prefixed/mcp/sdk/src/Client.php new file mode 100644 index 0000000..0069937 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Client.php @@ -0,0 +1,238 @@ + + */ +class Client +{ + private ?TransportInterface $transport = null; + public function __construct(private readonly Protocol $protocol, private readonly Configuration $config, private readonly LoggerInterface $logger = new NullLogger()) + { + } + /** + * Create a new client builder for fluent configuration. + */ + public static function builder() : Builder + { + return new Builder(); + } + /** + * Connect to an MCP server using the provided transport. + * + * @throws ConnectionException If connection or initialization fails + */ + public function connect(TransportInterface $transport) : void + { + $this->transport = $transport; + $this->protocol->connect($transport, $this->config); + $transport->connect(); + $this->logger->info('Client connected and initialized'); + } + /** + * Check if connected and initialized. + */ + public function isConnected() : bool + { + return null !== $this->transport && $this->protocol->getState()->isInitialized(); + } + /** + * Get server information from initialization. + */ + public function getServerInfo() : ?Implementation + { + return $this->protocol->getState()->getServerInfo(); + } + /** + * Get server instructions. + */ + public function getInstructions() : ?string + { + return $this->protocol->getState()->getInstructions(); + } + /** + * Send a ping request to the server. + */ + public function ping() : void + { + $request = new PingRequest(); + $this->sendRequest($request); + } + /** + * List available tools from the server. + */ + public function listTools(?string $cursor = null) : ListToolsResult + { + $request = new ListToolsRequest($cursor); + $response = $this->sendRequest($request); + return ListToolsResult::fromArray($response->result); + } + /** + * Call a tool on the server. + * + * @param string $name Tool name + * @param array $arguments Tool arguments + * @param (callable(float $progress, ?float $total, ?string $message): void)|null $onProgress + * Optional callback for progress updates + */ + public function callTool(string $name, array $arguments = [], ?callable $onProgress = null) : CallToolResult + { + $request = new CallToolRequest($name, $arguments); + $response = $this->sendRequest($request, $onProgress); + return CallToolResult::fromArray($response->result); + } + /** + * List available resources from the server. + */ + public function listResources(?string $cursor = null) : ListResourcesResult + { + $request = new ListResourcesRequest($cursor); + $response = $this->sendRequest($request); + return ListResourcesResult::fromArray($response->result); + } + /** + * List available resource templates from the server. + */ + public function listResourceTemplates(?string $cursor = null) : ListResourceTemplatesResult + { + $request = new ListResourceTemplatesRequest($cursor); + $response = $this->sendRequest($request); + return ListResourceTemplatesResult::fromArray($response->result); + } + /** + * Read a resource by URI. + * + * @param string $uri The resource URI + * @param (callable(float $progress, ?float $total, ?string $message): void)|null $onProgress + * Optional callback for progress updates + */ + public function readResource(string $uri, ?callable $onProgress = null) : ReadResourceResult + { + $request = new ReadResourceRequest($uri); + $response = $this->sendRequest($request, $onProgress); + return ReadResourceResult::fromArray($response->result); + } + /** + * List available prompts from the server. + */ + public function listPrompts(?string $cursor = null) : ListPromptsResult + { + $request = new ListPromptsRequest($cursor); + $response = $this->sendRequest($request); + return ListPromptsResult::fromArray($response->result); + } + /** + * Get a prompt from the server. + * + * @param string $name Prompt name + * @param array $arguments Prompt arguments + * @param (callable(float $progress, ?float $total, ?string $message): void)|null $onProgress + * Optional callback for progress updates + */ + public function getPrompt(string $name, array $arguments = [], ?callable $onProgress = null) : GetPromptResult + { + $request = new GetPromptRequest($name, $arguments); + $response = $this->sendRequest($request, $onProgress); + return GetPromptResult::fromArray($response->result); + } + /** + * Request completion suggestions for a prompt or resource argument. + * + * @param PromptReference|ResourceReference $ref The prompt or resource reference + * @param array{name: string, value: string} $argument The argument to complete + */ + public function complete(PromptReference|ResourceReference $ref, array $argument) : CompletionCompleteResult + { + $request = new CompletionCompleteRequest($ref, $argument); + $response = $this->sendRequest($request); + return CompletionCompleteResult::fromArray($response->result); + } + /** + * Set the minimum logging level for server log messages. + */ + public function setLoggingLevel(LoggingLevel $level) : void + { + $request = new SetLogLevelRequest($level); + $this->sendRequest($request); + } + /** + * Send a request to the server and wait for response. + * + * @param (callable(float $progress, ?float $total, ?string $message): void)|null $onProgress + * + * @return Response + * + * @throws RequestException|ConnectionException + */ + private function sendRequest(Request $request, ?callable $onProgress = null) : Response + { + if (!$this->isConnected()) { + throw new ConnectionException('Client is not connected. Call connect() first.'); + } + $withProgress = null !== $onProgress; + $fiber = new \Fiber(fn() => $this->protocol->request($request, $this->config->requestTimeout, $withProgress)); + $response = $this->transport->runRequest($fiber, $onProgress); + if ($response instanceof Error) { + throw RequestException::fromError($response); + } + return $response; + } + /** + * Disconnect from the server. + */ + public function disconnect() : void + { + if (null !== $this->transport) { + $this->transport->close(); + $this->transport = null; + $this->logger->info('Client disconnected'); + } + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Client/Builder.php b/vendor/prefixed/mcp/sdk/src/Client/Builder.php new file mode 100644 index 0000000..2f43dff --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Client/Builder.php @@ -0,0 +1,128 @@ + + */ +final class Builder +{ + private string $name = 'mcp-php-client'; + private string $version = '1.0.0'; + private ?string $description = null; + private ?ProtocolVersion $protocolVersion = null; + private ?ClientCapabilities $capabilities = null; + private int $initTimeout = 30; + private int $requestTimeout = 120; + private int $maxRetries = 3; + private ?LoggerInterface $logger = null; + /** @var NotificationHandlerInterface[] */ + private array $notificationHandlers = []; + /** @var RequestHandlerInterface[] */ + private array $requestHandlers = []; + /** + * Set the client name and version. + */ + public function setClientInfo(string $name, string $version, ?string $description = null) : self + { + $this->name = $name; + $this->version = $version; + $this->description = $description; + return $this; + } + /** + * Set the protocol version to use. + */ + public function setProtocolVersion(ProtocolVersion $protocolVersion) : self + { + $this->protocolVersion = $protocolVersion; + return $this; + } + /** + * Set client capabilities. + */ + public function setCapabilities(ClientCapabilities $capabilities) : self + { + $this->capabilities = $capabilities; + return $this; + } + /** + * Set initialization timeout in seconds. + */ + public function setInitTimeout(int $seconds) : self + { + $this->initTimeout = $seconds; + return $this; + } + /** + * Set request timeout in seconds. + */ + public function setRequestTimeout(int $seconds) : self + { + $this->requestTimeout = $seconds; + return $this; + } + /** + * Set maximum retry attempts for failed connections. + */ + public function setMaxRetries(int $retries) : self + { + $this->maxRetries = $retries; + return $this; + } + /** + * Set the logger. + */ + public function setLogger(LoggerInterface $logger) : self + { + $this->logger = $logger; + return $this; + } + /** + * Add a notification handler for server notifications. + */ + public function addNotificationHandler(NotificationHandlerInterface $handler) : self + { + $this->notificationHandlers[] = $handler; + return $this; + } + /** + * Add a request handler for server requests (e.g., sampling). + * + * @param RequestHandlerInterface $handler + */ + public function addRequestHandler(RequestHandlerInterface $handler) : self + { + $this->requestHandlers[] = $handler; + return $this; + } + /** + * Build the client instance. + */ + public function build() : Client + { + $logger = $this->logger ?? new NullLogger(); + $clientInfo = new Implementation($this->name, $this->version, $this->description); + $config = new Configuration(clientInfo: $clientInfo, capabilities: $this->capabilities ?? new ClientCapabilities(), protocolVersion: $this->protocolVersion ?? ProtocolVersion::V2025_06_18, initTimeout: $this->initTimeout, requestTimeout: $this->requestTimeout, maxRetries: $this->maxRetries); + $protocol = new Protocol(requestHandlers: $this->requestHandlers, notificationHandlers: $this->notificationHandlers, logger: $logger); + return new Client($protocol, $config, $logger); + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Client/Configuration.php b/vendor/prefixed/mcp/sdk/src/Client/Configuration.php new file mode 100644 index 0000000..8998e2d --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Client/Configuration.php @@ -0,0 +1,26 @@ + + */ +class Configuration +{ + public function __construct(public readonly Implementation $clientInfo, public readonly ClientCapabilities $capabilities, public readonly ProtocolVersion $protocolVersion = ProtocolVersion::V2025_06_18, public readonly int $initTimeout = 30, public readonly int $requestTimeout = 120, public readonly int $maxRetries = 3) + { + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Client/Handler/Notification/LoggingNotificationHandler.php b/vendor/prefixed/mcp/sdk/src/Client/Handler/Notification/LoggingNotificationHandler.php new file mode 100644 index 0000000..d3a2d28 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Client/Handler/Notification/LoggingNotificationHandler.php @@ -0,0 +1,37 @@ + + */ +class LoggingNotificationHandler implements NotificationHandlerInterface +{ + /** + * @param callable(LoggingMessageNotification): void $callback + */ + public function __construct(private readonly mixed $callback) + { + } + public function supports(Notification $notification) : bool + { + return $notification instanceof LoggingMessageNotification; + } + public function handle(Notification $notification) : void + { + \assert($notification instanceof LoggingMessageNotification); + ($this->callback)($notification); + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Client/Handler/Notification/NotificationHandlerInterface.php b/vendor/prefixed/mcp/sdk/src/Client/Handler/Notification/NotificationHandlerInterface.php new file mode 100644 index 0000000..c8c65e1 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Client/Handler/Notification/NotificationHandlerInterface.php @@ -0,0 +1,29 @@ + + */ +interface NotificationHandlerInterface +{ + /** + * Check if this handler supports the given notification. + */ + public function supports(Notification $notification) : bool; + /** + * Handle the notification. + */ + public function handle(Notification $notification) : void; +} diff --git a/vendor/prefixed/mcp/sdk/src/Client/Handler/Notification/ProgressNotificationHandler.php b/vendor/prefixed/mcp/sdk/src/Client/Handler/Notification/ProgressNotificationHandler.php new file mode 100644 index 0000000..e98b921 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Client/Handler/Notification/ProgressNotificationHandler.php @@ -0,0 +1,41 @@ + + * + * @internal + */ +class ProgressNotificationHandler implements NotificationHandlerInterface +{ + public function __construct(private readonly ClientStateInterface $state) + { + } + public function supports(Notification $notification) : bool + { + return $notification instanceof ProgressNotification; + } + public function handle(Notification $notification) : void + { + if (!$notification instanceof ProgressNotification) { + return; + } + $this->state->storeProgress((string) $notification->progressToken, $notification->progress, $notification->total, $notification->message); + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Client/Handler/Request/RequestHandlerInterface.php b/vendor/prefixed/mcp/sdk/src/Client/Handler/Request/RequestHandlerInterface.php new file mode 100644 index 0000000..4eddfa2 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Client/Handler/Request/RequestHandlerInterface.php @@ -0,0 +1,35 @@ + + */ +interface RequestHandlerInterface +{ + /** + * Check if this handler supports the given request. + */ + public function supports(Request $request) : bool; + /** + * Handle the request and return a response or error. + * + * @return Response|Error + */ + public function handle(Request $request) : Response|Error; +} diff --git a/vendor/prefixed/mcp/sdk/src/Client/Handler/Request/SamplingCallbackInterface.php b/vendor/prefixed/mcp/sdk/src/Client/Handler/Request/SamplingCallbackInterface.php new file mode 100644 index 0000000..f4173df --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Client/Handler/Request/SamplingCallbackInterface.php @@ -0,0 +1,23 @@ + + * + * @author Kyrian Obikwelu + */ +class SamplingRequestHandler implements RequestHandlerInterface +{ + public function __construct(private readonly SamplingCallbackInterface $callback, private readonly LoggerInterface $logger = new NullLogger()) + { + } + public function supports(Request $request) : bool + { + return $request instanceof CreateSamplingMessageRequest; + } + /** + * @return Response|Error + */ + public function handle(Request $request) : Response|Error + { + \assert($request instanceof CreateSamplingMessageRequest); + try { + $result = $this->callback->__invoke($request); + return new Response($request->getId(), $result); + } catch (SamplingException $e) { + $this->logger->error('Sampling failed: ' . $e->getMessage()); + return Error::forInternalError($e->getMessage(), $request->getId()); + } catch (\Throwable $e) { + $this->logger->error('Unexpected error during sampling', ['exception' => $e]); + return Error::forInternalError('Error while sampling LLM', $request->getId()); + } + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Client/Protocol.php b/vendor/prefixed/mcp/sdk/src/Client/Protocol.php new file mode 100644 index 0000000..a00de4d --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Client/Protocol.php @@ -0,0 +1,238 @@ + + */ +class Protocol +{ + private ?TransportInterface $transport = null; + private ClientStateInterface $state; + private MessageFactory $messageFactory; + private LoggerInterface $logger; + /** @var NotificationHandlerInterface[] */ + private array $notificationHandlers; + /** + * @param RequestHandlerInterface[] $requestHandlers + * @param NotificationHandlerInterface[] $notificationHandlers + */ + public function __construct(private readonly array $requestHandlers = [], array $notificationHandlers = [], ?MessageFactory $messageFactory = null, ?LoggerInterface $logger = null) + { + $this->state = new ClientState(); + $this->messageFactory = $messageFactory ?? MessageFactory::make(); + $this->logger = $logger ?? new NullLogger(); + $this->notificationHandlers = [new ProgressNotificationHandler($this->state), ...$notificationHandlers]; + } + /** + * Connect this protocol to a transport. + * + * Sets up message handling callbacks. + * + * @param TransportInterface $transport The transport to connect + * @param Configuration $config The client configuration for initialization + */ + public function connect(TransportInterface $transport, Configuration $config) : void + { + $this->transport = $transport; + $transport->setState($this->state); + $transport->onInitialize(fn() => $this->initialize($config)); + $transport->onMessage($this->processMessage(...)); + $transport->onError(fn(\Throwable $e) => $this->logger->error('Transport error', ['exception' => $e])); + $this->logger->info('Protocol connected to transport', ['transport' => $transport::class]); + } + /** + * Perform the MCP initialization handshake. + * + * Sends InitializeRequest and waits for response, then sends InitializedNotification. + * + * @param Configuration $config The client configuration + * + * @return Response>|Error + */ + public function initialize(Configuration $config) : Response|Error + { + $request = new InitializeRequest($config->protocolVersion->value, $config->capabilities, $config->clientInfo); + $response = $this->request($request, $config->initTimeout); + if ($response instanceof Response) { + $initResult = InitializeResult::fromArray($response->result); + $this->state->setServerInfo($initResult->serverInfo); + $this->state->setInstructions($initResult->instructions); + $this->state->setInitialized(\true); + $this->sendNotification(new InitializedNotification()); + $this->logger->info('Initialization complete', ['server' => $initResult->serverInfo->name]); + } + return $response; + } + /** + * Send a request to the server and wait for response. + * + * If a response is immediately available (sync HTTP), returns it. + * Otherwise, suspends the Fiber and waits for the transport to resume it. + * + * @param Request $request The request to send + * @param int $timeout The timeout in seconds + * @param bool $withProgress Whether to attach a progress token to the request + * + * @return Response>|Error + */ + public function request(Request $request, int $timeout, bool $withProgress = \false) : Response|Error + { + $requestId = $this->state->nextRequestId(); + $request = $request->withId($requestId); + if ($withProgress) { + $progressToken = "prog-{$requestId}"; + $request = $request->withMeta(['progressToken' => $progressToken]); + } + $this->state->addPendingRequest($requestId, $timeout); + $this->sendRequest($request); + $immediate = $this->state->consumeResponse($requestId); + if (null !== $immediate) { + $this->logger->debug('Received immediate response', ['id' => $requestId]); + return $immediate; + } + $this->logger->debug('Suspending fiber for response', ['id' => $requestId]); + return \Fiber::suspend(['type' => 'await_response', 'request_id' => $requestId, 'timeout' => $timeout]); + } + /** + * Send a request to the server. + */ + private function sendRequest(Request $request) : void + { + $this->logger->debug('Sending request', ['id' => $request->getId(), 'method' => $request::getMethod()]); + $encoded = json_encode($request, \JSON_THROW_ON_ERROR); + $this->transport?->send($encoded); + } + /** + * Send a notification to the server (fire and forget). + */ + public function sendNotification(Notification $notification) : void + { + $this->logger->debug('Sending notification', ['method' => $notification::getMethod()]); + $encoded = json_encode($notification, \JSON_THROW_ON_ERROR); + $this->transport?->send($encoded); + } + /** + * Send a response back to the server (for server-initiated requests). + * + * @param Response|Error $response + */ + private function sendResponse(Response|Error $response) : void + { + $this->logger->debug('Sending response', ['id' => $response->getId()]); + $encoded = json_encode($response, \JSON_THROW_ON_ERROR); + $this->transport?->send($encoded); + } + /** + * Process an incoming message from the server. + * + * Routes to appropriate handler based on message type. + */ + public function processMessage(string $input) : void + { + $this->logger->debug('Received message', ['input' => $input]); + try { + $messages = $this->messageFactory->create($input); + } catch (\JsonException $e) { + $this->logger->warning('Failed to parse message', ['exception' => $e]); + return; + } + foreach ($messages as $message) { + if ($message instanceof Response || $message instanceof Error) { + $this->handleResponse($message); + } elseif ($message instanceof Request) { + $this->handleRequest($message); + } elseif ($message instanceof Notification) { + $this->handleNotification($message); + } + } + } + /** + * Handle a response from the server. + * + * This stores it in session. The transport will pick it up and resume the Fiber. + * + * @param Response|Error $response + */ + private function handleResponse(Response|Error $response) : void + { + $requestId = $response->getId(); + $this->logger->debug('Handling response', ['id' => $requestId]); + $this->state->storeResponse($requestId, $response->jsonSerialize()); + } + /** + * Handle a request from the server (e.g., sampling request). + */ + private function handleRequest(Request $request) : void + { + $method = $request::getMethod(); + $this->logger->debug('Received server request', ['method' => $method, 'id' => $request->getId()]); + foreach ($this->requestHandlers as $handler) { + if ($handler->supports($request)) { + try { + $response = $handler->handle($request); + } catch (\Throwable $e) { + $this->logger->error('Unexpected error while handling request', ['method' => $method, 'exception' => $e]); + $response = Error::forInternalError(\sprintf('Unexpected error while handling "%s" request', $method), $request->getId()); + } + $this->sendResponse($response); + return; + } + } + $error = Error::forMethodNotFound(\sprintf('Client does not handle "%s" requests.', $method), $request->getId()); + $this->sendResponse($error); + } + /** + * Handle a notification from the server. + */ + private function handleNotification(Notification $notification) : void + { + $method = $notification::getMethod(); + $this->logger->debug('Received server notification', ['method' => $method]); + foreach ($this->notificationHandlers as $handler) { + if ($handler->supports($notification)) { + try { + $handler->handle($notification); + } catch (\Throwable $e) { + $this->logger->warning('Notification handler failed', ['exception' => $e]); + } + return; + } + } + } + public function getState() : ClientStateInterface + { + return $this->state; + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Client/State/ClientState.php b/vendor/prefixed/mcp/sdk/src/Client/State/ClientState.php new file mode 100644 index 0000000..1f6ba47 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Client/State/ClientState.php @@ -0,0 +1,104 @@ + + */ +class ClientState implements ClientStateInterface +{ + private int $requestIdCounter = 1; + private bool $initialized = \false; + private ?Implementation $serverInfo = null; + private ?string $instructions = null; + /** @var array */ + private array $pendingRequests = []; + /** @var array> */ + private array $responses = []; + /** @var array */ + private array $progressUpdates = []; + public function nextRequestId() : int + { + return $this->requestIdCounter++; + } + public function addPendingRequest(int|string $requestId, int $timeout) : void + { + $this->pendingRequests[$requestId] = ['request_id' => $requestId, 'timestamp' => time(), 'timeout' => $timeout]; + } + public function removePendingRequest(int|string $requestId) : void + { + unset($this->pendingRequests[$requestId]); + } + public function getPendingRequests() : array + { + return $this->pendingRequests; + } + public function storeResponse(int|string $requestId, array $responseData) : void + { + $this->responses[$requestId] = $responseData; + } + public function consumeResponse(int|string $requestId) : Response|Error|null + { + if (!isset($this->responses[$requestId])) { + return null; + } + $data = $this->responses[$requestId]; + unset($this->responses[$requestId]); + $this->removePendingRequest($requestId); + if (isset($data['error'])) { + return Error::fromArray($data); + } + return Response::fromArray($data); + } + public function setInitialized(bool $initialized) : void + { + $this->initialized = $initialized; + } + public function isInitialized() : bool + { + return $this->initialized; + } + public function setServerInfo(Implementation $serverInfo) : void + { + $this->serverInfo = $serverInfo; + } + public function getServerInfo() : ?Implementation + { + return $this->serverInfo; + } + public function setInstructions(?string $instructions) : void + { + $this->instructions = $instructions; + } + public function getInstructions() : ?string + { + return $this->instructions; + } + public function storeProgress(string $token, float $progress, ?float $total, ?string $message) : void + { + $this->progressUpdates[] = ['token' => $token, 'progress' => $progress, 'total' => $total, 'message' => $message]; + } + public function consumeProgressUpdates() : array + { + $updates = $this->progressUpdates; + $this->progressUpdates = []; + return $updates; + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Client/State/ClientStateInterface.php b/vendor/prefixed/mcp/sdk/src/Client/State/ClientStateInterface.php new file mode 100644 index 0000000..07c218f --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Client/State/ClientStateInterface.php @@ -0,0 +1,100 @@ + + */ +interface ClientStateInterface +{ + /** + * Get the next request ID for outgoing requests. + */ + public function nextRequestId() : int; + /** + * Add a pending request to track. + * + * @param int|string $requestId The request ID + * @param int $timeout Timeout in seconds + */ + public function addPendingRequest(int|string $requestId, int $timeout) : void; + /** + * Remove a pending request. + */ + public function removePendingRequest(int|string $requestId) : void; + /** + * Get all pending requests. + * + * @return array + */ + public function getPendingRequests() : array; + /** + * Store a received response. + * + * @param int|string $requestId The request ID + * @param array $responseData The raw response data + */ + public function storeResponse(int|string $requestId, array $responseData) : void; + /** + * Check and consume a response for a request ID. + * + * @return Response>|Error|null + */ + public function consumeResponse(int|string $requestId) : Response|Error|null; + /** + * Set initialization state. + */ + public function setInitialized(bool $initialized) : void; + /** + * Check if connection is initialized. + */ + public function isInitialized() : bool; + /** + * Store the server info from initialization. + */ + public function setServerInfo(Implementation $serverInfo) : void; + /** + * Get the server info from initialization. + */ + public function getServerInfo() : ?Implementation; + /** + * Store the server instructions from initialization. + */ + public function setInstructions(?string $instructions) : void; + /** + * Get the server instructions from initialization. + */ + public function getInstructions() : ?string; + /** + * Store progress data received from a notification. + * + * @param string $token The progress token + * @param float $progress Current progress value + * @param float|null $total Total progress value (if known) + * @param string|null $message Progress message + */ + public function storeProgress(string $token, float $progress, ?float $total, ?string $message) : void; + /** + * Consume all pending progress updates. + * + * @return array + */ + public function consumeProgressUpdates() : array; +} diff --git a/vendor/prefixed/mcp/sdk/src/Client/Transport/BaseTransport.php b/vendor/prefixed/mcp/sdk/src/Client/Transport/BaseTransport.php new file mode 100644 index 0000000..78f02c8 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Client/Transport/BaseTransport.php @@ -0,0 +1,107 @@ + + */ +abstract class BaseTransport implements TransportInterface +{ + /** @var callable(): mixed|null */ + protected $initializeCallback; + /** @var callable(string): void|null */ + protected $messageCallback; + /** @var callable(\Throwable): void|null */ + protected $errorCallback; + /** @var callable(string): void|null */ + protected $closeCallback; + protected ?ClientStateInterface $state = null; + protected LoggerInterface $logger; + public function __construct(?LoggerInterface $logger = null) + { + $this->logger = $logger ?? new NullLogger(); + } + public function onInitialize(callable $listener) : void + { + $this->initializeCallback = $listener; + } + public function onMessage(callable $listener) : void + { + $this->messageCallback = $listener; + } + public function onError(callable $listener) : void + { + $this->errorCallback = $listener; + } + public function onClose(callable $listener) : void + { + $this->closeCallback = $listener; + } + public function setState(ClientStateInterface $state) : void + { + $this->state = $state; + } + /** + * Perform initialization via the registered callback. + * + * @return mixed The result from the initialization callback + * + * @throws RuntimeException If no initialize listener is registered + */ + protected function handleInitialize() : mixed + { + if (!\is_callable($this->initializeCallback)) { + throw new RuntimeException('No initialize listener registered'); + } + return ($this->initializeCallback)(); + } + /** + * Handle an incoming message from the server. + */ + protected function handleMessage(string $message) : void + { + if (\is_callable($this->messageCallback)) { + try { + ($this->messageCallback)($message); + } catch (\Throwable $e) { + $this->handleError($e); + } + } + } + /** + * Handle a transport error. + */ + protected function handleError(\Throwable $error) : void + { + $this->logger->error('Transport error', ['exception' => $error]); + if (\is_callable($this->errorCallback)) { + ($this->errorCallback)($error); + } + } + /** + * Handle connection close. + */ + protected function handleClose(string $reason) : void + { + $this->logger->info('Transport closed', ['reason' => $reason]); + if (\is_callable($this->closeCallback)) { + ($this->closeCallback)($reason); + } + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Client/Transport/HttpTransport.php b/vendor/prefixed/mcp/sdk/src/Client/Transport/HttpTransport.php new file mode 100644 index 0000000..a54bc56 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Client/Transport/HttpTransport.php @@ -0,0 +1,232 @@ + + */ +class HttpTransport extends BaseTransport +{ + private ClientInterface $httpClient; + private RequestFactoryInterface $requestFactory; + private StreamFactoryInterface $streamFactory; + private ?string $sessionId = null; + /** @var McpFiber|null */ + private ?\Fiber $activeFiber = null; + /** @var (callable(float, ?float, ?string): void)|null */ + private $activeProgressCallback; + /** @var StreamInterface|null Active SSE stream being read */ + private ?StreamInterface $activeStream = null; + /** @var string Buffer for incomplete SSE data */ + private string $sseBuffer = ''; + /** + * @param string $endpoint The MCP server endpoint URL + * @param array $headers Additional headers to send + * @param ClientInterface|null $httpClient PSR-18 HTTP client (auto-discovered if null) + * @param RequestFactoryInterface|null $requestFactory PSR-17 request factory (auto-discovered if null) + * @param StreamFactoryInterface|null $streamFactory PSR-17 stream factory (auto-discovered if null) + */ + public function __construct(private readonly string $endpoint, private readonly array $headers = [], ?ClientInterface $httpClient = null, ?RequestFactoryInterface $requestFactory = null, ?StreamFactoryInterface $streamFactory = null, ?LoggerInterface $logger = null) + { + parent::__construct($logger); + $this->httpClient = $httpClient ?? Psr18ClientDiscovery::find(); + $this->requestFactory = $requestFactory ?? Psr17FactoryDiscovery::findRequestFactory(); + $this->streamFactory = $streamFactory ?? Psr17FactoryDiscovery::findStreamFactory(); + } + public function connect() : void + { + $this->activeFiber = new \Fiber(fn() => $this->handleInitialize()); + $this->activeFiber->start(); + while (!$this->activeFiber->isTerminated()) { + $this->tick(); + } + $result = $this->activeFiber->getReturn(); + $this->activeFiber = null; + if ($result instanceof Error) { + throw new ConnectionException('Initialization failed: ' . $result->message); + } + $this->logger->info('HTTP client connected and initialized', ['endpoint' => $this->endpoint]); + } + public function send(string $data) : void + { + $request = $this->requestFactory->createRequest('POST', $this->endpoint)->withHeader('Content-Type', 'application/json')->withHeader('Accept', 'application/json, text/event-stream')->withBody($this->streamFactory->createStream($data)); + if (null !== $this->sessionId) { + $request = $request->withHeader('Mcp-Session-Id', $this->sessionId); + } + foreach ($this->headers as $name => $value) { + $request = $request->withHeader($name, $value); + } + $this->logger->debug('Sending HTTP request', ['data' => $data]); + try { + $response = $this->httpClient->sendRequest($request); + } catch (\Throwable $e) { + $this->handleError($e); + throw new ConnectionException('HTTP request failed: ' . $e->getMessage(), 0, $e); + } + if ($response->hasHeader('Mcp-Session-Id')) { + $this->sessionId = $response->getHeaderLine('Mcp-Session-Id'); + $this->logger->debug('Received session ID', ['session_id' => $this->sessionId]); + } + $contentType = $response->getHeaderLine('Content-Type'); + if (str_contains($contentType, 'text/event-stream')) { + $this->activeStream = $response->getBody(); + $this->sseBuffer = ''; + } elseif (str_contains($contentType, 'application/json')) { + $body = $response->getBody()->getContents(); + if (!empty($body)) { + $this->handleMessage($body); + } + } + } + /** + * @param McpFiber $fiber + * @param (callable(float $progress, ?float $total, ?string $message): void)|null $onProgress + */ + public function runRequest(\Fiber $fiber, ?callable $onProgress = null) : Response|Error + { + $this->activeFiber = $fiber; + $this->activeProgressCallback = $onProgress; + $fiber->start(); + while (!$fiber->isTerminated()) { + $this->tick(); + } + $this->activeFiber = null; + $this->activeProgressCallback = null; + $this->activeStream = null; + return $fiber->getReturn(); + } + public function close() : void + { + if (null !== $this->sessionId) { + try { + $request = $this->requestFactory->createRequest('DELETE', $this->endpoint)->withHeader('Mcp-Session-Id', $this->sessionId); + foreach ($this->headers as $name => $value) { + $request = $request->withHeader($name, $value); + } + $this->httpClient->sendRequest($request); + $this->logger->info('Session closed', ['session_id' => $this->sessionId]); + } catch (\Throwable $e) { + $this->logger->warning('Failed to close session', ['error' => $e->getMessage()]); + } + } + $this->sessionId = null; + $this->activeStream = null; + $this->handleClose('Transport closed'); + } + private function tick() : void + { + $this->processSSEStream(); + $this->processProgress(); + $this->processFiber(); + usleep(1000); + // 1ms + } + /** + * Read SSE data incrementally from active stream. + */ + private function processSSEStream() : void + { + if (null === $this->activeStream) { + return; + } + if (!$this->activeStream->eof()) { + $chunk = $this->activeStream->read(4096); + if ('' !== $chunk) { + $this->sseBuffer .= $chunk; + } + } + while (\false !== ($pos = strpos($this->sseBuffer, "\n\n"))) { + $event = substr($this->sseBuffer, 0, $pos); + $this->sseBuffer = substr($this->sseBuffer, $pos + 2); + if (!empty(trim($event))) { + $this->processSSEEvent($event); + } + } + if ($this->activeStream->eof() && empty($this->sseBuffer)) { + $this->activeStream = null; + } + } + /** + * Parse a single SSE event and handle the message. + */ + private function processSSEEvent(string $event) : void + { + $data = ''; + foreach (explode("\n", $event) as $line) { + if (str_starts_with($line, 'data:')) { + $data .= trim(substr($line, 5)); + } + } + if (!empty($data)) { + $this->handleMessage($data); + } + } + /** + * Process pending progress updates from session and execute callback. + */ + private function processProgress() : void + { + if (null === $this->activeProgressCallback || null === $this->state) { + return; + } + $updates = $this->state->consumeProgressUpdates(); + foreach ($updates as $update) { + try { + ($this->activeProgressCallback)($update['progress'], $update['total'], $update['message']); + } catch (\Throwable $e) { + $this->logger->warning('Progress callback failed', ['exception' => $e]); + } + } + } + private function processFiber() : void + { + if (null === $this->activeFiber || !$this->activeFiber->isSuspended()) { + return; + } + if (null === $this->state) { + return; + } + $pendingRequests = $this->state->getPendingRequests(); + foreach ($pendingRequests as $pending) { + $requestId = $pending['request_id']; + $timestamp = $pending['timestamp']; + $timeout = $pending['timeout']; + $response = $this->state->consumeResponse($requestId); + if (null !== $response) { + $this->logger->debug('Resuming fiber with response', ['request_id' => $requestId]); + $this->activeFiber->resume($response); + return; + } + if (time() - $timestamp >= $timeout) { + $this->logger->warning('Request timed out', ['request_id' => $requestId]); + $error = Error::forInternalError('Request timed out', $requestId); + $this->activeFiber->resume($error); + return; + } + } + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Client/Transport/StdioTransport.php b/vendor/prefixed/mcp/sdk/src/Client/Transport/StdioTransport.php new file mode 100644 index 0000000..460715a --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Client/Transport/StdioTransport.php @@ -0,0 +1,226 @@ + + */ +class StdioTransport extends BaseTransport +{ + /** @var resource|null */ + private $process; + /** @var resource|null */ + private $stdin; + /** @var resource|null */ + private $stdout; + /** @var resource|null */ + private $stderr; + private string $inputBuffer = ''; + /** @var McpFiber|null */ + private ?\Fiber $activeFiber = null; + /** @var (callable(float, ?float, ?string): void)|null */ + private $activeProgressCallback; + /** + * @param string $command The command to run + * @param array $args Command arguments + * @param string|null $cwd Working directory + * @param array|null $env Environment variables + */ + public function __construct(private readonly string $command, private readonly array $args = [], private readonly ?string $cwd = null, private readonly ?array $env = null, ?LoggerInterface $logger = null) + { + parent::__construct($logger); + } + public function connect() : void + { + $this->spawnProcess(); + $this->activeFiber = new \Fiber(fn() => $this->handleInitialize()); + $this->activeFiber->start(); + while (!$this->activeFiber->isTerminated()) { + $this->tick(); + } + $result = $this->activeFiber->getReturn(); + $this->activeFiber = null; + if ($result instanceof Error) { + $this->close(); + throw new ConnectionException('Initialization failed: ' . $result->message); + } + $this->logger->info('Client connected and initialized'); + } + public function send(string $data) : void + { + if (null === $this->stdin || !\is_resource($this->stdin)) { + throw new ConnectionException('Process stdin not available'); + } + fwrite($this->stdin, $data . "\n"); + fflush($this->stdin); + $this->logger->debug('Sent message to server', ['data' => $data]); + } + /** + * @param McpFiber $fiber + * @param (callable(float $progress, ?float $total, ?string $message): void)|null $onProgress + */ + public function runRequest(\Fiber $fiber, ?callable $onProgress = null) : Response|Error + { + $this->activeFiber = $fiber; + $this->activeProgressCallback = $onProgress; + $fiber->start(); + while (!$fiber->isTerminated()) { + $this->tick(); + } + $this->activeFiber = null; + $this->activeProgressCallback = null; + return $fiber->getReturn(); + } + public function close() : void + { + if (\is_resource($this->stdin)) { + fclose($this->stdin); + $this->stdin = null; + } + if (\is_resource($this->stdout)) { + fclose($this->stdout); + $this->stdout = null; + } + if (\is_resource($this->stderr)) { + fclose($this->stderr); + $this->stderr = null; + } + if (\is_resource($this->process)) { + proc_terminate($this->process, 15); + // SIGTERM + proc_close($this->process); + $this->process = null; + } + $this->handleClose('Transport closed'); + } + private function spawnProcess() : void + { + $descriptors = [ + 0 => ['pipe', 'r'], + // stdin + 1 => ['pipe', 'w'], + // stdout + 2 => ['pipe', 'w'], + ]; + $cmd = escapeshellcmd($this->command); + foreach ($this->args as $arg) { + $cmd .= ' ' . escapeshellarg($arg); + } + $this->process = proc_open($cmd, $descriptors, $pipes, $this->cwd, $this->env); + if (!\is_resource($this->process)) { + throw new ConnectionException('Failed to start process: ' . $cmd); + } + $this->stdin = $pipes[0]; + $this->stdout = $pipes[1]; + $this->stderr = $pipes[2]; + // Set non-blocking mode for reading + stream_set_blocking($this->stdout, \false); + stream_set_blocking($this->stderr, \false); + $this->logger->info('Started MCP server process', ['command' => $cmd]); + } + private function tick() : void + { + $this->processInput(); + $this->processProgress(); + $this->processFiber(); + $this->processStderr(); + usleep(1000); + // 1ms + } + /** + * Process pending progress updates from session and execute callback. + */ + private function processProgress() : void + { + if (null === $this->activeProgressCallback || null === $this->state) { + return; + } + $updates = $this->state->consumeProgressUpdates(); + foreach ($updates as $update) { + try { + ($this->activeProgressCallback)($update['progress'], $update['total'], $update['message']); + } catch (\Throwable $e) { + $this->logger->warning('Progress callback failed', ['exception' => $e]); + } + } + } + private function processInput() : void + { + if (null === $this->stdout || !\is_resource($this->stdout)) { + return; + } + $data = fread($this->stdout, 8192); + if (\false !== $data && '' !== $data) { + $this->inputBuffer .= $data; + } + while (\false !== ($pos = strpos($this->inputBuffer, "\n"))) { + $line = substr($this->inputBuffer, 0, $pos); + $this->inputBuffer = substr($this->inputBuffer, $pos + 1); + $trimmed = trim($line); + if (!empty($trimmed)) { + $this->handleMessage($trimmed); + } + } + } + private function processFiber() : void + { + if (null === $this->activeFiber || !$this->activeFiber->isSuspended()) { + return; + } + if (null === $this->state) { + return; + } + $pendingRequests = $this->state->getPendingRequests(); + foreach ($pendingRequests as $pending) { + $requestId = $pending['request_id']; + $timestamp = $pending['timestamp']; + $timeout = $pending['timeout']; + // Check if response arrived + $response = $this->state->consumeResponse($requestId); + if (null !== $response) { + $this->logger->debug('Resuming fiber with response', ['request_id' => $requestId]); + $this->activeFiber->resume($response); + return; + } + // Check timeout + if (time() - $timestamp >= $timeout) { + $this->logger->warning('Request timed out', ['request_id' => $requestId]); + $error = Error::forInternalError('Request timed out', $requestId); + $this->activeFiber->resume($error); + return; + } + } + } + private function processStderr() : void + { + if (null === $this->stderr || !\is_resource($this->stderr)) { + return; + } + $stderr = fread($this->stderr, 8192); + if (\false !== $stderr && '' !== $stderr) { + $this->logger->debug('Server stderr', ['output' => trim($stderr)]); + } + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Client/Transport/TransportInterface.php b/vendor/prefixed/mcp/sdk/src/Client/Transport/TransportInterface.php new file mode 100644 index 0000000..c310931 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Client/Transport/TransportInterface.php @@ -0,0 +1,97 @@ +|Error) + * @phpstan-type FiberResume (Response|Error) + * @phpstan-type FiberSuspend array{type: 'await_response', request_id: int, timeout: int} + * @phpstan-type McpFiber \Fiber + * + * @author Kyrian Obikwelu + */ +interface TransportInterface +{ + /** + * Connect to the MCP server and perform initialization handshake. + * + * This method blocks until: + * - Initialization completes successfully + * - Connection fails (throws ConnectionException) + * + * @throws \Mcp\Exception\ConnectionException + */ + public function connect() : void; + /** + * Send a message to the server immediately. + * + * @param string $data JSON-encoded message + */ + public function send(string $data) : void; + /** + * Run a request fiber to completion. + * + * The transport starts the fiber, runs its internal loop, and resumes + * the fiber when a response arrives or timeout occurs. + * + * During the loop, the transport checks session for progress data and + * executes the callback if provided. + * + * @param McpFiber $fiber The fiber to execute + * @param (callable(float $progress, ?float $total, ?string $message): void)|null $onProgress + * Optional callback for progress updates + * + * @return Response>|Error The response or error + */ + public function runRequest(\Fiber $fiber, ?callable $onProgress = null) : Response|Error; + /** + * Close the transport and clean up resources. + */ + public function close() : void; + /** + * Register callback for initialization handshake. + * + * The callback should return a Fiber that performs the initialization. + * + * @param callable(): mixed $callback + */ + public function onInitialize(callable $callback) : void; + /** + * Register callback for incoming messages from server. + * + * @param callable(string $message): void $callback + */ + public function onMessage(callable $callback) : void; + /** + * Register callback for transport errors. + * + * @param callable(\Throwable $error): void $callback + */ + public function onError(callable $callback) : void; + /** + * Register callback for when connection closes. + * + * @param callable(string $reason): void $callback + */ + public function onClose(callable $callback) : void; + /** + * Set the client state for runtime state management. + */ + public function setState(ClientStateInterface $state) : void; +} diff --git a/vendor/prefixed/mcp/sdk/src/Event/ErrorEvent.php b/vendor/prefixed/mcp/sdk/src/Event/ErrorEvent.php index f6beada..ca31eed 100644 --- a/vendor/prefixed/mcp/sdk/src/Event/ErrorEvent.php +++ b/vendor/prefixed/mcp/sdk/src/Event/ErrorEvent.php @@ -1,6 +1,5 @@ + */ +class ConnectionException extends Exception +{ +} diff --git a/vendor/prefixed/mcp/sdk/src/Exception/RequestException.php b/vendor/prefixed/mcp/sdk/src/Exception/RequestException.php new file mode 100644 index 0000000..d1efabc --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Exception/RequestException.php @@ -0,0 +1,35 @@ + + */ +class RequestException extends Exception +{ + private ?Error $error; + public function __construct(string $message = '', int $code = 0, ?\Throwable $previous = null, ?Error $error = null) + { + parent::__construct($message, $code, $previous); + $this->error = $error; + } + public static function fromError(Error $error) : self + { + return new self($error->message, $error->code, null, $error); + } + public function getError() : ?Error + { + return $this->error; + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Exception/SamplingException.php b/vendor/prefixed/mcp/sdk/src/Exception/SamplingException.php new file mode 100644 index 0000000..8002827 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Exception/SamplingException.php @@ -0,0 +1,23 @@ + + */ +final class SamplingException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/vendor/prefixed/mcp/sdk/src/Exception/TimeoutException.php b/vendor/prefixed/mcp/sdk/src/Exception/TimeoutException.php new file mode 100644 index 0000000..f8248e8 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Exception/TimeoutException.php @@ -0,0 +1,20 @@ + + */ +class TimeoutException extends Exception +{ +} diff --git a/vendor/prefixed/mcp/sdk/src/Schema/ClientCapabilities.php b/vendor/prefixed/mcp/sdk/src/Schema/ClientCapabilities.php index 2b5365f..bcf6ce0 100644 --- a/vendor/prefixed/mcp/sdk/src/Schema/ClientCapabilities.php +++ b/vendor/prefixed/mcp/sdk/src/Schema/ClientCapabilities.php @@ -61,9 +61,9 @@ public static function fromArray(array $data) : self * sampling?: object, * elicitation?: object, * experimental?: object, - * } + * }|\stdClass */ - public function jsonSerialize() : array + public function jsonSerialize() : array|object { $data = []; if ($this->roots || $this->rootsListChanged) { @@ -81,6 +81,6 @@ public function jsonSerialize() : array if ($this->experimental) { $data['experimental'] = (object) $this->experimental; } - return $data; + return $data ?: new \stdClass(); } } diff --git a/vendor/prefixed/mcp/sdk/src/Schema/Elicitation/AbstractSchemaDefinition.php b/vendor/prefixed/mcp/sdk/src/Schema/Elicitation/AbstractSchemaDefinition.php index 597d4af..c9ef81b 100644 --- a/vendor/prefixed/mcp/sdk/src/Schema/Elicitation/AbstractSchemaDefinition.php +++ b/vendor/prefixed/mcp/sdk/src/Schema/Elicitation/AbstractSchemaDefinition.php @@ -1,6 +1,5 @@ $properties Property definitions keyed by name - * @param string[] $required Array of required property names + * @param array $properties Property definitions keyed by name + * @param string[] $required Array of required property names */ public function __construct(public readonly array $properties, public readonly array $required = []) { @@ -58,10 +57,54 @@ public static function fromArray(array $data) : self if (!\is_array($propertyData)) { throw new InvalidArgumentException(\sprintf('Property "%s" must be an array.', $name)); } - $properties[$name] = PrimitiveSchemaDefinition::fromArray($propertyData); + $properties[$name] = self::createSchemaDefinition($propertyData); } return new self(properties: $properties, required: $data['required'] ?? []); } + /** + * Create a schema definition from array data. + * + * @param array $data + */ + private static function createSchemaDefinition(array $data) : AbstractSchemaDefinition + { + if (!isset($data['type']) || !\is_string($data['type'])) { + throw new InvalidArgumentException('Missing or invalid "type" for schema definition.'); + } + return match ($data['type']) { + 'string' => self::resolveStringType($data), + 'integer', 'number' => NumberSchemaDefinition::fromArray($data), + 'boolean' => BooleanSchemaDefinition::fromArray($data), + 'array' => self::resolveArrayType($data), + default => throw new InvalidArgumentException(\sprintf('Unsupported type "%s". Supported types are: string, integer, number, boolean, array.', $data['type'])), + }; + } + /** + * @param array $data + */ + private static function resolveStringType(array $data) : AbstractSchemaDefinition + { + if (isset($data['oneOf'])) { + return TitledEnumSchemaDefinition::fromArray($data); + } + if (isset($data['enum'])) { + return EnumSchemaDefinition::fromArray($data); + } + return StringSchemaDefinition::fromArray($data); + } + /** + * @param array $data + */ + private static function resolveArrayType(array $data) : AbstractSchemaDefinition + { + if (isset($data['items']['anyOf'])) { + return TitledMultiSelectEnumSchemaDefinition::fromArray($data); + } + if (isset($data['items']['enum'])) { + return MultiSelectEnumSchemaDefinition::fromArray($data); + } + throw new InvalidArgumentException('Array type must have "items" with either "enum" or "anyOf".'); + } /** * @return array{ * type: string, diff --git a/vendor/prefixed/mcp/sdk/src/Schema/Elicitation/EnumSchemaDefinition.php b/vendor/prefixed/mcp/sdk/src/Schema/Elicitation/EnumSchemaDefinition.php index 575cda5..10c9719 100644 --- a/vendor/prefixed/mcp/sdk/src/Schema/Elicitation/EnumSchemaDefinition.php +++ b/vendor/prefixed/mcp/sdk/src/Schema/Elicitation/EnumSchemaDefinition.php @@ -1,6 +1,5 @@ $maxItems) { + throw new InvalidArgumentException('minItems cannot be greater than maxItems.'); + } + if (null !== $default) { + foreach ($default as $value) { + if (!\in_array($value, $enum, \true)) { + throw new InvalidArgumentException(\sprintf('Default value "%s" is not in the enum array.', $value)); + } + } + } + } + /** + * @param array{ + * title: string, + * items: array{type: string, enum: string[]}, + * description?: string, + * default?: string[], + * minItems?: int, + * maxItems?: int, + * } $data + */ + public static function fromArray(array $data) : self + { + self::validateTitle($data, 'multi-select enum'); + if (!isset($data['items']['enum']) || !\is_array($data['items']['enum'])) { + throw new InvalidArgumentException('Missing or invalid "items.enum" for multi-select enum schema definition.'); + } + return new self(title: $data['title'], enum: $data['items']['enum'], description: $data['description'] ?? null, default: $data['default'] ?? null, minItems: isset($data['minItems']) ? (int) $data['minItems'] : null, maxItems: isset($data['maxItems']) ? (int) $data['maxItems'] : null); + } + /** + * @return array + */ + public function jsonSerialize() : array + { + $data = $this->buildBaseJson('array'); + $data['items'] = ['type' => 'string', 'enum' => $this->enum]; + if (null !== $this->default) { + $data['default'] = $this->default; + } + if (null !== $this->minItems) { + $data['minItems'] = $this->minItems; + } + if (null !== $this->maxItems) { + $data['maxItems'] = $this->maxItems; + } + return $data; + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Schema/Elicitation/NumberSchemaDefinition.php b/vendor/prefixed/mcp/sdk/src/Schema/Elicitation/NumberSchemaDefinition.php index 93a434e..d484aae 100644 --- a/vendor/prefixed/mcp/sdk/src/Schema/Elicitation/NumberSchemaDefinition.php +++ b/vendor/prefixed/mcp/sdk/src/Schema/Elicitation/NumberSchemaDefinition.php @@ -1,6 +1,5 @@ - */ -final class PrimitiveSchemaDefinition -{ - /** - * Create a schema definition from array data. - * - * @param array{ - * type: string, - * title: string, - * description?: string, - * default?: mixed, - * enum?: string[], - * enumNames?: string[], - * format?: string, - * minLength?: int, - * maxLength?: int, - * minimum?: int|float, - * maximum?: int|float, - * } $data - */ - public static function fromArray(array $data) : StringSchemaDefinition|NumberSchemaDefinition|BooleanSchemaDefinition|EnumSchemaDefinition - { - if (!isset($data['type']) || !\is_string($data['type'])) { - throw new InvalidArgumentException('Missing or invalid "type" for primitive schema definition.'); - } - return match ($data['type']) { - 'string' => isset($data['enum']) ? EnumSchemaDefinition::fromArray($data) : StringSchemaDefinition::fromArray($data), - 'integer', 'number' => NumberSchemaDefinition::fromArray($data), - 'boolean' => BooleanSchemaDefinition::fromArray($data), - default => throw new InvalidArgumentException(\sprintf('Unsupported primitive type "%s". Supported types are: string, integer, number, boolean.', $data['type'])), - }; - } -} diff --git a/vendor/prefixed/mcp/sdk/src/Schema/Elicitation/StringSchemaDefinition.php b/vendor/prefixed/mcp/sdk/src/Schema/Elicitation/StringSchemaDefinition.php index 52b6350..0a36a9a 100644 --- a/vendor/prefixed/mcp/sdk/src/Schema/Elicitation/StringSchemaDefinition.php +++ b/vendor/prefixed/mcp/sdk/src/Schema/Elicitation/StringSchemaDefinition.php @@ -1,6 +1,5 @@ $oneOf Array of const/title pairs + * @param string|null $description Optional description/help text + * @param string|null $default Optional default value (must match a const) + */ + public function __construct(string $title, public readonly array $oneOf, ?string $description = null, public readonly ?string $default = null) + { + parent::__construct($title, $description); + if ([] === $oneOf) { + throw new InvalidArgumentException('oneOf array must not be empty.'); + } + $consts = []; + foreach ($oneOf as $item) { + if (!isset($item['const']) || !\is_string($item['const'])) { + throw new InvalidArgumentException('Each oneOf item must have a string "const" property.'); + } + if (!isset($item['title']) || !\is_string($item['title'])) { + throw new InvalidArgumentException('Each oneOf item must have a string "title" property.'); + } + $consts[] = $item['const']; + } + if (null !== $default && !\in_array($default, $consts, \true)) { + throw new InvalidArgumentException(\sprintf('Default value "%s" is not in the oneOf const values.', $default)); + } + } + /** + * @param array{ + * title: string, + * oneOf: list, + * description?: string, + * default?: string, + * } $data + */ + public static function fromArray(array $data) : self + { + self::validateTitle($data, 'titled enum'); + if (!isset($data['oneOf']) || !\is_array($data['oneOf'])) { + throw new InvalidArgumentException('Missing or invalid "oneOf" for titled enum schema definition.'); + } + return new self(title: $data['title'], oneOf: $data['oneOf'], description: $data['description'] ?? null, default: $data['default'] ?? null); + } + /** + * @return array + */ + public function jsonSerialize() : array + { + $data = $this->buildBaseJson('string'); + $data['oneOf'] = $this->oneOf; + if (null !== $this->default) { + $data['default'] = $this->default; + } + return $data; + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Schema/Elicitation/TitledMultiSelectEnumSchemaDefinition.php b/vendor/prefixed/mcp/sdk/src/Schema/Elicitation/TitledMultiSelectEnumSchemaDefinition.php new file mode 100644 index 0000000..34e4e6f --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Schema/Elicitation/TitledMultiSelectEnumSchemaDefinition.php @@ -0,0 +1,100 @@ + $anyOf Array of const/title pairs + * @param string|null $description Optional description/help text + * @param string[]|null $default Optional default selected values (must be subset of anyOf consts) + * @param int|null $minItems Optional minimum number of selections + * @param int|null $maxItems Optional maximum number of selections + */ + public function __construct(string $title, public readonly array $anyOf, ?string $description = null, public readonly ?array $default = null, public readonly ?int $minItems = null, public readonly ?int $maxItems = null) + { + parent::__construct($title, $description); + if ([] === $anyOf) { + throw new InvalidArgumentException('anyOf array must not be empty.'); + } + $consts = []; + foreach ($anyOf as $item) { + if (!isset($item['const']) || !\is_string($item['const'])) { + throw new InvalidArgumentException('Each anyOf item must have a string "const" property.'); + } + if (!isset($item['title']) || !\is_string($item['title'])) { + throw new InvalidArgumentException('Each anyOf item must have a string "title" property.'); + } + $consts[] = $item['const']; + } + if (null !== $minItems && $minItems < 0) { + throw new InvalidArgumentException('minItems must be non-negative.'); + } + if (null !== $maxItems && $maxItems < 0) { + throw new InvalidArgumentException('maxItems must be non-negative.'); + } + if (null !== $minItems && null !== $maxItems && $minItems > $maxItems) { + throw new InvalidArgumentException('minItems cannot be greater than maxItems.'); + } + if (null !== $default) { + foreach ($default as $value) { + if (!\in_array($value, $consts, \true)) { + throw new InvalidArgumentException(\sprintf('Default value "%s" is not in the anyOf const values.', $value)); + } + } + } + } + /** + * @param array{ + * title: string, + * items: array{anyOf: list}, + * description?: string, + * default?: string[], + * minItems?: int, + * maxItems?: int, + * } $data + */ + public static function fromArray(array $data) : self + { + self::validateTitle($data, 'titled multi-select enum'); + if (!isset($data['items']['anyOf']) || !\is_array($data['items']['anyOf'])) { + throw new InvalidArgumentException('Missing or invalid "items.anyOf" for titled multi-select enum schema definition.'); + } + return new self(title: $data['title'], anyOf: $data['items']['anyOf'], description: $data['description'] ?? null, default: $data['default'] ?? null, minItems: isset($data['minItems']) ? (int) $data['minItems'] : null, maxItems: isset($data['maxItems']) ? (int) $data['maxItems'] : null); + } + /** + * @return array + */ + public function jsonSerialize() : array + { + $data = $this->buildBaseJson('array'); + $data['items'] = ['anyOf' => $this->anyOf]; + if (null !== $this->default) { + $data['default'] = $this->default; + } + if (null !== $this->minItems) { + $data['minItems'] = $this->minItems; + } + if (null !== $this->maxItems) { + $data['maxItems'] = $this->maxItems; + } + return $data; + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Schema/Enum/ElicitAction.php b/vendor/prefixed/mcp/sdk/src/Schema/Enum/ElicitAction.php index 5f3b9af..662753d 100644 --- a/vendor/prefixed/mcp/sdk/src/Schema/Enum/ElicitAction.php +++ b/vendor/prefixed/mcp/sdk/src/Schema/Enum/ElicitAction.php @@ -1,6 +1,5 @@ $meta Optional metadata */ - public function __construct(public readonly string $name, public readonly ?string $description = null, public readonly ?array $arguments = null, public readonly ?array $icons = null, public readonly ?array $meta = null) + public function __construct(public readonly string $name, public readonly ?string $title = null, public readonly ?string $description = null, public readonly ?array $arguments = null, public readonly ?array $icons = null, public readonly ?array $meta = null) { if (null !== $this->arguments) { foreach ($this->arguments as $arg) { @@ -61,11 +63,12 @@ public static function fromArray(array $data) : self if (!empty($data['_meta']) && !\is_array($data['_meta'])) { throw new InvalidArgumentException('Invalid "_meta" in Prompt data.'); } - return new self(name: $data['name'], description: $data['description'] ?? null, arguments: $arguments, icons: isset($data['icons']) && \is_array($data['icons']) ? array_map(Icon::fromArray(...), $data['icons']) : null, meta: isset($data['_meta']) ? $data['_meta'] : null); + return new self(name: $data['name'], title: $data['title'] ?? null, description: $data['description'] ?? null, arguments: $arguments, icons: isset($data['icons']) && \is_array($data['icons']) ? array_map(Icon::fromArray(...), $data['icons']) : null, meta: isset($data['_meta']) ? $data['_meta'] : null); } /** * @return array{ * name: string, + * title?: string, * description?: string, * arguments?: array, * icons?: Icon[], @@ -75,6 +78,9 @@ public static function fromArray(array $data) : self public function jsonSerialize() : array { $data = ['name' => $this->name]; + if (null !== $this->title) { + $data['title'] = $this->title; + } if (null !== $this->description) { $data['description'] = $this->description; } diff --git a/vendor/prefixed/mcp/sdk/src/Schema/Request/CallToolRequest.php b/vendor/prefixed/mcp/sdk/src/Schema/Request/CallToolRequest.php index afaa125..a511e64 100644 --- a/vendor/prefixed/mcp/sdk/src/Schema/Request/CallToolRequest.php +++ b/vendor/prefixed/mcp/sdk/src/Schema/Request/CallToolRequest.php @@ -49,6 +49,6 @@ protected static function fromParams(?array $params) : static */ protected function getParams() : array { - return ['name' => $this->name, 'arguments' => $this->arguments]; + return ['name' => $this->name, 'arguments' => $this->arguments ?: new \stdClass()]; } } diff --git a/vendor/prefixed/mcp/sdk/src/Schema/Request/CreateSamplingMessageRequest.php b/vendor/prefixed/mcp/sdk/src/Schema/Request/CreateSamplingMessageRequest.php index 689a99c..2e4b935 100644 --- a/vendor/prefixed/mcp/sdk/src/Schema/Request/CreateSamplingMessageRequest.php +++ b/vendor/prefixed/mcp/sdk/src/Schema/Request/CreateSamplingMessageRequest.php @@ -60,11 +60,25 @@ protected static function fromParams(?array $params) : static if (!isset($params['maxTokens']) || !\is_int($params['maxTokens'])) { throw new InvalidArgumentException('Missing or invalid "maxTokens" parameter for sampling/createMessage.'); } + $messages = []; + foreach ($params['messages'] as $messageData) { + if ($messageData instanceof SamplingMessage) { + $messages[] = $messageData; + } elseif (\is_array($messageData)) { + $messages[] = SamplingMessage::fromArray($messageData); + } else { + throw new InvalidArgumentException('Invalid message format in sampling/createMessage.'); + } + } $preferences = null; if (isset($params['preferences'])) { $preferences = ModelPreferences::fromArray($params['preferences']); } - return new self($params['messages'], $params['maxTokens'], $preferences, $params['systemPrompt'] ?? null, $params['includeContext'] ?? null, $params['temperature'] ?? null, $params['stopSequences'] ?? null, $params['metadata'] ?? null); + $includeContext = null; + if (isset($params['includeContext']) && \is_string($params['includeContext'])) { + $includeContext = SamplingContext::tryFrom($params['includeContext']); + } + return new self($messages, $params['maxTokens'], $preferences, $params['systemPrompt'] ?? null, $includeContext, $params['temperature'] ?? null, $params['stopSequences'] ?? null, $params['metadata'] ?? null); } /** * @return array{ diff --git a/vendor/prefixed/mcp/sdk/src/Schema/Request/ElicitRequest.php b/vendor/prefixed/mcp/sdk/src/Schema/Request/ElicitRequest.php index 9a13737..2bfdf7b 100644 --- a/vendor/prefixed/mcp/sdk/src/Schema/Request/ElicitRequest.php +++ b/vendor/prefixed/mcp/sdk/src/Schema/Request/ElicitRequest.php @@ -1,6 +1,5 @@ |null $arguments the arguments to pass to the prompt + * @param string $name the name of the prompt to get + * @param array|null $arguments the arguments to pass to the prompt */ public function __construct(public readonly string $name, public readonly ?array $arguments = null) { @@ -47,7 +47,7 @@ protected static function fromParams(?array $params) : static return new self($params['name'], $arguments); } /** - * @return array{name: string, arguments?: array} + * @return array{name: string, arguments?: array} */ protected function getParams() : array { diff --git a/vendor/prefixed/mcp/sdk/src/Schema/Result/CompletionCompleteResult.php b/vendor/prefixed/mcp/sdk/src/Schema/Result/CompletionCompleteResult.php index 6fbf789..ee0bccc 100644 --- a/vendor/prefixed/mcp/sdk/src/Schema/Result/CompletionCompleteResult.php +++ b/vendor/prefixed/mcp/sdk/src/Schema/Result/CompletionCompleteResult.php @@ -50,4 +50,12 @@ public function jsonSerialize() : array } return ['completion' => $completion]; } + /** + * @param array $data + */ + public static function fromArray(array $data) : self + { + $completion = $data['completion'] ?? []; + return new self($completion['values'] ?? [], $completion['total'] ?? null, $completion['hasMore'] ?? null); + } } diff --git a/vendor/prefixed/mcp/sdk/src/Schema/Result/ElicitResult.php b/vendor/prefixed/mcp/sdk/src/Schema/Result/ElicitResult.php index 3d3b48d..a357748 100644 --- a/vendor/prefixed/mcp/sdk/src/Schema/Result/ElicitResult.php +++ b/vendor/prefixed/mcp/sdk/src/Schema/Result/ElicitResult.php @@ -1,6 +1,5 @@ $meta Optional metadata * @param ToolOutputSchema|null $outputSchema optional JSON Schema object (as a PHP array) defining the expected output structure */ - public function __construct(public readonly string $name, public readonly array $inputSchema, public readonly ?string $description, public readonly ?ToolAnnotations $annotations, public readonly ?array $icons = null, public readonly ?array $meta = null, public readonly ?array $outputSchema = null) + public function __construct(public readonly string $name, public readonly ?string $title, public readonly array $inputSchema, public readonly ?string $description, public readonly ?ToolAnnotations $annotations, public readonly ?array $icons = null, public readonly ?array $meta = null, public readonly ?array $outputSchema = null) { if (!isset($inputSchema['type']) || 'object' !== $inputSchema['type']) { throw new InvalidArgumentException('Tool inputSchema must be a JSON Schema of type "object".'); @@ -82,11 +84,12 @@ public static function fromArray(array $data) : self } $outputSchema = self::normalizeSchemaProperties($data['outputSchema']); } - return new self($data['name'], $inputSchema, isset($data['description']) && \is_string($data['description']) ? $data['description'] : null, isset($data['annotations']) && \is_array($data['annotations']) ? ToolAnnotations::fromArray($data['annotations']) : null, isset($data['icons']) && \is_array($data['icons']) ? array_map(Icon::fromArray(...), $data['icons']) : null, isset($data['_meta']) && \is_array($data['_meta']) ? $data['_meta'] : null, $outputSchema); + return new self(name: $data['name'], title: isset($data['title']) && \is_string($data['title']) ? $data['title'] : null, inputSchema: $inputSchema, description: isset($data['description']) && \is_string($data['description']) ? $data['description'] : null, annotations: isset($data['annotations']) && \is_array($data['annotations']) ? ToolAnnotations::fromArray($data['annotations']) : null, icons: isset($data['icons']) && \is_array($data['icons']) ? array_map(Icon::fromArray(...), $data['icons']) : null, meta: isset($data['_meta']) && \is_array($data['_meta']) ? $data['_meta'] : null, outputSchema: $outputSchema); } /** * @return array{ * name: string, + * title?: string, * inputSchema: ToolInputSchema, * description?: string, * annotations?: ToolAnnotations, @@ -97,7 +100,11 @@ public static function fromArray(array $data) : self */ public function jsonSerialize() : array { - $data = ['name' => $this->name, 'inputSchema' => $this->inputSchema]; + $data = ['name' => $this->name]; + if (null !== $this->title) { + $data['title'] = $this->title; + } + $data['inputSchema'] = $this->inputSchema; if (null !== $this->description) { $data['description'] = $this->description; } diff --git a/vendor/prefixed/mcp/sdk/src/Schema/ToolAnnotations.php b/vendor/prefixed/mcp/sdk/src/Schema/ToolAnnotations.php index 19d0d0f..258b4d1 100644 --- a/vendor/prefixed/mcp/sdk/src/Schema/ToolAnnotations.php +++ b/vendor/prefixed/mcp/sdk/src/Schema/ToolAnnotations.php @@ -27,7 +27,7 @@ class ToolAnnotations implements \JsonSerializable { /** - * @param ?string $title a human-readable title for the tool + * @param ?string $title a human-readable title for the tool — deprecated for display in favor of `Mcp\Schema\Tool::$title` per MCP spec revision 2025-06-18; retained for backward compatibility * @param ?bool $readOnlyHint if true, the tool does not modify its environment * @param ?bool $destructiveHint If true, the tool may perform destructive updates to its environment. If false, the tool performs only additive updates. * @param ?bool $idempotentHint If true, calling the tool repeatedly with the same arguments will have no additional effect on the its environment. (This property is meaningful only when `readOnlyHint == false`) diff --git a/vendor/prefixed/mcp/sdk/src/Server/Builder.php b/vendor/prefixed/mcp/sdk/src/Server/Builder.php index 09c79d0..23b348c 100644 --- a/vendor/prefixed/mcp/sdk/src/Server/Builder.php +++ b/vendor/prefixed/mcp/sdk/src/Server/Builder.php @@ -21,7 +21,9 @@ use Matomo\Dependencies\McpServer\Mcp\Capability\Registry\Loader\DiscoveryLoader; use Matomo\Dependencies\McpServer\Mcp\Capability\Registry\Loader\LoaderInterface; use Matomo\Dependencies\McpServer\Mcp\Capability\Registry\ReferenceHandler; +use Matomo\Dependencies\McpServer\Mcp\Capability\Registry\ReferenceHandlerInterface; use Matomo\Dependencies\McpServer\Mcp\Capability\RegistryInterface; +use Matomo\Dependencies\McpServer\Mcp\Exception\InvalidArgumentException; use Matomo\Dependencies\McpServer\Mcp\JsonRpc\MessageFactory; use Matomo\Dependencies\McpServer\Mcp\Schema\Annotations; use Matomo\Dependencies\McpServer\Mcp\Schema\Enum\ProtocolVersion; @@ -35,14 +37,15 @@ use Matomo\Dependencies\McpServer\Mcp\Server\Resource\SessionSubscriptionManager; use Matomo\Dependencies\McpServer\Mcp\Server\Resource\SubscriptionManagerInterface; use Matomo\Dependencies\McpServer\Mcp\Server\Session\InMemorySessionStore; -use Matomo\Dependencies\McpServer\Mcp\Server\Session\SessionFactory; -use Matomo\Dependencies\McpServer\Mcp\Server\Session\SessionFactoryInterface; +use Matomo\Dependencies\McpServer\Mcp\Server\Session\SessionManager; +use Matomo\Dependencies\McpServer\Mcp\Server\Session\SessionManagerInterface; use Matomo\Dependencies\McpServer\Mcp\Server\Session\SessionStoreInterface; use Psr\Container\ContainerInterface; use Psr\EventDispatcher\EventDispatcherInterface; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; use Psr\SimpleCache\CacheInterface; +use Symfony\Component\Finder\Finder; /** * @phpstan-import-type Handler from ElementReference * @@ -58,10 +61,10 @@ final class Builder private ?EventDispatcherInterface $eventDispatcher = null; private ?ContainerInterface $container = null; private ?SchemaGeneratorInterface $schemaGenerator = null; + private ?ReferenceHandlerInterface $referenceHandler = null; private ?DiscovererInterface $discoverer = null; - private ?SessionFactoryInterface $sessionFactory = null; + private ?SessionManagerInterface $sessionManager = null; private ?SessionStoreInterface $sessionStore = null; - private int $sessionTtl = 3600; private int $paginationLimit = 50; private ?string $instructions = null; private ?ProtocolVersion $protocolVersion = null; @@ -77,6 +80,7 @@ final class Builder * @var array{ * handler: Handler, * name: ?string, + * title: ?string, * description: ?string, * annotations: ?ToolAnnotations, * icons: ?Icon[], @@ -247,6 +251,11 @@ public function setSchemaGenerator(SchemaGeneratorInterface $schemaGenerator) : $this->schemaGenerator = $schemaGenerator; return $this; } + public function setReferenceHandler(ReferenceHandlerInterface $referenceHandler) : self + { + $this->referenceHandler = $referenceHandler; + return $this; + } public function setDiscoverer(DiscovererInterface $discoverer) : self { $this->discoverer = $discoverer; @@ -257,11 +266,13 @@ public function setResourceSubscriptionManager(SubscriptionManagerInterface $sub $this->subscriptionManager = $subscriptionManager; return $this; } - public function setSession(SessionStoreInterface $sessionStore, SessionFactoryInterface $sessionFactory = new SessionFactory(), int $ttl = 3600) : self + public function setSession(?SessionStoreInterface $sessionStore = null, ?SessionManagerInterface $sessionManager = null) : self { - $this->sessionFactory = $sessionFactory; $this->sessionStore = $sessionStore; - $this->sessionTtl = $ttl; + $this->sessionManager = $sessionManager; + if (null !== $sessionManager && null !== $sessionStore) { + throw new InvalidArgumentException('Cannot set both SessionStore and SessionManager. Set only one or the other.'); + } return $this; } /** @@ -285,14 +296,15 @@ public function setProtocolVersion(ProtocolVersion $protocolVersion) : self * Manually registers a tool handler. * * @param Handler $handler + * @param ?string $title Optional human-readable title for display in UI * @param array|null $inputSchema * @param ?Icon[] $icons * @param array|null $meta * @param array|null $outputSchema */ - public function addTool(callable|array|string $handler, ?string $name = null, ?string $description = null, ?ToolAnnotations $annotations = null, ?array $inputSchema = null, ?array $icons = null, ?array $meta = null, ?array $outputSchema = null) : self + public function addTool(callable|array|string $handler, ?string $name = null, ?string $title = null, ?string $description = null, ?ToolAnnotations $annotations = null, ?array $inputSchema = null, ?array $icons = null, ?array $meta = null, ?array $outputSchema = null) : self { - $this->tools[] = compact('handler', 'name', 'description', 'annotations', 'inputSchema', 'icons', 'meta', 'outputSchema'); + $this->tools[] = compact('handler', 'name', 'title', 'description', 'annotations', 'inputSchema', 'icons', 'meta', 'outputSchema'); return $this; } /** @@ -325,9 +337,9 @@ public function addResourceTemplate(\Closure|array|string $handler, string $uriT * @param ?Icon[] $icons * @param array|null $meta */ - public function addPrompt(\Closure|array|string $handler, ?string $name = null, ?string $description = null, ?array $icons = null, ?array $meta = null) : self + public function addPrompt(\Closure|array|string $handler, ?string $name = null, ?string $title = null, ?string $description = null, ?array $icons = null, ?array $meta = null) : self { - $this->prompts[] = compact('handler', 'name', 'description', 'icons', 'meta'); + $this->prompts[] = compact('handler', 'name', 'title', 'description', 'icons', 'meta'); return $this; } /** @@ -358,12 +370,14 @@ public function build() : Server $registry = $this->registry ?? new Registry($this->eventDispatcher, $logger); $subscriptionManager = $this->subscriptionManager ?? new SessionSubscriptionManager($logger); $loaders = [...$this->loaders, new ArrayLoader($this->tools, $this->resources, $this->resourceTemplates, $this->prompts, $logger, $this->schemaGenerator)]; - $sessionTtl = $this->sessionTtl ?? 3600; - $sessionFactory = $this->sessionFactory ?? new SessionFactory(); - $sessionStore = $this->sessionStore ?? new InMemorySessionStore($sessionTtl); + $sessionManager = $this->sessionManager ?? new SessionManager($this->sessionStore ?? new InMemorySessionStore(), $logger); if (null !== $this->discoveryBasePath) { - $discoverer = $this->discoverer ?? $this->createDiscoverer($logger); - $loaders[] = new DiscoveryLoader($this->discoveryBasePath, $this->discoveryScanDirs, $this->discoveryExcludeDirs, $discoverer); + if (null !== $this->discoverer || class_exists(Finder::class)) { + $discoverer = $this->discoverer ?? $this->createDiscoverer($logger); + $loaders[] = new DiscoveryLoader($this->discoveryBasePath, $this->discoveryScanDirs, $this->discoveryExcludeDirs, $discoverer); + } else { + $logger->warning('File-based discovery requires symfony/finder. Skipping automatic discovery. Run: composer require symfony/finder'); + } } foreach ($loaders as $loader) { $loader->load($registry); @@ -372,10 +386,10 @@ public function build() : Server $capabilities = $this->serverCapabilities ?? new ServerCapabilities(tools: $registry->hasTools(), toolsListChanged: $this->eventDispatcher instanceof EventDispatcherInterface, resources: $registry->hasResources() || $registry->hasResourceTemplates(), resourcesSubscribe: $registry->hasResources() || $registry->hasResourceTemplates(), resourcesListChanged: $this->eventDispatcher instanceof EventDispatcherInterface, prompts: $registry->hasPrompts(), promptsListChanged: $this->eventDispatcher instanceof EventDispatcherInterface, logging: \true, completions: \true); $serverInfo = $this->serverInfo ?? new Implementation(); $configuration = new Configuration($serverInfo, $capabilities, $this->paginationLimit, $this->instructions, $this->protocolVersion); - $referenceHandler = new ReferenceHandler($container); + $referenceHandler = $this->referenceHandler ?? new ReferenceHandler($container); $requestHandlers = array_merge($this->requestHandlers, [new Handler\Request\CallToolHandler($registry, $referenceHandler, $logger), new Handler\Request\CompletionCompleteHandler($registry, $container), new Handler\Request\GetPromptHandler($registry, $referenceHandler, $logger), new Handler\Request\InitializeHandler($configuration), new Handler\Request\ListPromptsHandler($registry, $this->paginationLimit), new Handler\Request\ListResourcesHandler($registry, $this->paginationLimit), new Handler\Request\ListResourceTemplatesHandler($registry, $this->paginationLimit), new Handler\Request\ListToolsHandler($registry, $this->paginationLimit), new Handler\Request\PingHandler(), new Handler\Request\ReadResourceHandler($registry, $referenceHandler, $logger), new Handler\Request\ResourceSubscribeHandler($registry, $subscriptionManager, $logger), new Handler\Request\ResourceUnsubscribeHandler($registry, $subscriptionManager, $logger), new Handler\Request\SetLogLevelHandler()]); $notificationHandlers = array_merge($this->notificationHandlers, [new Handler\Notification\InitializedHandler()]); - $protocol = new Protocol(requestHandlers: $requestHandlers, notificationHandlers: $notificationHandlers, messageFactory: $messageFactory, sessionFactory: $sessionFactory, sessionStore: $sessionStore, logger: $logger, eventDispatcher: $this->eventDispatcher); + $protocol = new Protocol(requestHandlers: $requestHandlers, notificationHandlers: $notificationHandlers, messageFactory: $messageFactory, sessionManager: $sessionManager, logger: $logger, eventDispatcher: $this->eventDispatcher); return new Server($protocol, $logger); } private function createDiscoverer(LoggerInterface $logger) : DiscovererInterface diff --git a/vendor/prefixed/mcp/sdk/src/Server/Handler/Request/CallToolHandler.php b/vendor/prefixed/mcp/sdk/src/Server/Handler/Request/CallToolHandler.php index 8669f8f..1b504f4 100644 --- a/vendor/prefixed/mcp/sdk/src/Server/Handler/Request/CallToolHandler.php +++ b/vendor/prefixed/mcp/sdk/src/Server/Handler/Request/CallToolHandler.php @@ -48,7 +48,7 @@ public function handle(Request $request, SessionInterface $session) : Response|E { \assert($request instanceof CallToolRequest); $toolName = $request->name; - $arguments = $request->arguments ?? []; + $arguments = $request->arguments; $this->logger->debug('Executing tool', ['name' => $toolName, 'arguments' => $arguments]); try { $reference = $this->registry->getTool($toolName); diff --git a/vendor/prefixed/mcp/sdk/src/Server/NativeClock.php b/vendor/prefixed/mcp/sdk/src/Server/NativeClock.php index 18b5254..001f2b2 100644 --- a/vendor/prefixed/mcp/sdk/src/Server/NativeClock.php +++ b/vendor/prefixed/mcp/sdk/src/Server/NativeClock.php @@ -1,6 +1,5 @@ >> $requestHandlers * @param array $notificationHandlers */ - public function __construct(private readonly array $requestHandlers, private readonly array $notificationHandlers, private readonly MessageFactory $messageFactory, private readonly SessionFactoryInterface $sessionFactory, private readonly SessionStoreInterface $sessionStore, private readonly LoggerInterface $logger = new NullLogger(), private readonly ?EventDispatcherInterface $eventDispatcher = null) + public function __construct(private readonly array $requestHandlers, private readonly array $notificationHandlers, private readonly MessageFactory $messageFactory, private readonly SessionManagerInterface $sessionManager, private readonly LoggerInterface $logger = new NullLogger(), private readonly ?EventDispatcherInterface $eventDispatcher = null) { } /** @@ -88,7 +87,7 @@ public function connect(TransportInterface $transport) : void public function processInput(TransportInterface $transport, string $input, ?Uuid $sessionId) : void { $this->logger->info('Received message to process.', ['message' => $input]); - $this->gcSessions(); + $this->sessionManager->gc(); try { $messages = $this->messageFactory->create($input); } catch (\JsonException $e) { @@ -305,7 +304,7 @@ private function queueOutgoing(Request|Notification|Response|Error $message, arr */ public function consumeOutgoingMessages(Uuid $sessionId) : array { - $session = $this->sessionFactory->createWithId($sessionId, $this->sessionStore); + $session = $this->sessionManager->createWithId($sessionId); $queue = $session->get(self::SESSION_OUTGOING_QUEUE, []); $session->set(self::SESSION_OUTGOING_QUEUE, []); $session->save(); @@ -322,7 +321,7 @@ public function consumeOutgoingMessages(Uuid $sessionId) : array */ public function checkResponse(int $requestId, Uuid $sessionId) : Response|Error|null { - $session = $this->sessionFactory->createWithId($sessionId, $this->sessionStore); + $session = $this->sessionManager->createWithId($sessionId); $responseData = $session->get(self::SESSION_RESPONSES . ".{$requestId}"); if (null === $responseData) { return null; @@ -350,7 +349,7 @@ public function checkResponse(int $requestId, Uuid $sessionId) : Response|Error| */ public function getPendingRequests(Uuid $sessionId) : array { - $session = $this->sessionFactory->createWithId($sessionId, $this->sessionStore); + $session = $this->sessionManager->createWithId($sessionId); return $session->get(self::SESSION_PENDING_REQUESTS, []); } /** @@ -368,7 +367,7 @@ public function handleFiberYield(mixed $yieldedValue, ?Uuid $sessionId) : void $this->logger->warning('Fiber yielded unexpected payload.', ['payload' => $yieldedValue, 'session_id' => $sessionId->toRfc4122()]); return; } - $session = $this->sessionFactory->createWithId($sessionId, $this->sessionStore); + $session = $this->sessionManager->createWithId($sessionId); $payloadSessionId = $yieldedValue['session_id'] ?? null; if (\is_string($payloadSessionId) && $payloadSessionId !== $sessionId->toRfc4122()) { $this->logger->warning('Fiber yielded payload with mismatched session ID.', ['payload_session_id' => $payloadSessionId, 'expected_session_id' => $sessionId->toRfc4122()]); @@ -430,7 +429,7 @@ private function resolveSession(TransportInterface $transport, ?Uuid $sessionId, $this->sendResponse($transport, $error, null); return null; } - $session = $this->sessionFactory->create($this->sessionStore); + $session = $this->sessionManager->create(); $this->logger->debug('Created new session for initialize', ['session_id' => $session->getId()->toRfc4122()]); $transport->setSessionId($session->getId()); return $session; @@ -440,33 +439,19 @@ private function resolveSession(TransportInterface $transport, ?Uuid $sessionId, $this->sendResponse($transport, $error, null, ['status_code' => 400]); return null; } - if (!$this->sessionStore->exists($sessionId)) { + if (!$this->sessionManager->exists($sessionId)) { $error = Error::forInvalidRequest('Session not found or has expired.'); $this->sendResponse($transport, $error, null, ['status_code' => 404]); return null; } - return $this->sessionFactory->createWithId($sessionId, $this->sessionStore); - } - /** - * Run garbage collection on expired sessions. - * Uses the session store's internal TTL configuration. - */ - private function gcSessions() : void - { - if (random_int(0, 100) > 1) { - return; - } - $deletedSessions = $this->sessionStore->gc(); - if (!empty($deletedSessions)) { - $this->logger->debug('Garbage collected expired sessions.', ['count' => \count($deletedSessions), 'session_ids' => array_map(static fn(Uuid $id) => $id->toRfc4122(), $deletedSessions)]); - } + return $this->sessionManager->createWithId($sessionId); } /** * Destroy a specific session. */ public function destroySession(Uuid $sessionId) : void { - $this->sessionStore->destroy($sessionId); + $this->sessionManager->destroy($sessionId); $this->logger->info('Session destroyed.', ['session_id' => $sessionId->toRfc4122()]); } } diff --git a/vendor/prefixed/mcp/sdk/src/Server/Session/FileSessionStore.php b/vendor/prefixed/mcp/sdk/src/Server/Session/FileSessionStore.php index 16dac7a..e200424 100644 --- a/vendor/prefixed/mcp/sdk/src/Server/Session/FileSessionStore.php +++ b/vendor/prefixed/mcp/sdk/src/Server/Session/FileSessionStore.php @@ -1,6 +1,5 @@ id; } - public function getStore() : SessionStoreInterface - { - return $this->store; - } public function save() : bool { - return $this->store->write($this->id, json_encode($this->data, \JSON_THROW_ON_ERROR)); + return $this->store->write($this->id, json_encode($this->readData(), \JSON_THROW_ON_ERROR)); } public function get(string $key, mixed $default = null) : mixed { diff --git a/vendor/prefixed/mcp/sdk/src/Server/Session/SessionFactory.php b/vendor/prefixed/mcp/sdk/src/Server/Session/SessionFactory.php deleted file mode 100644 index 2800188..0000000 --- a/vendor/prefixed/mcp/sdk/src/Server/Session/SessionFactory.php +++ /dev/null @@ -1,29 +0,0 @@ - - */ -class SessionFactory implements SessionFactoryInterface -{ - public function create(SessionStoreInterface $store) : SessionInterface - { - return new Session($store, Uuid::v4()); - } - public function createWithId(Uuid $id, SessionStoreInterface $store) : SessionInterface - { - return new Session($store, $id); - } -} diff --git a/vendor/prefixed/mcp/sdk/src/Server/Session/SessionInterface.php b/vendor/prefixed/mcp/sdk/src/Server/Session/SessionInterface.php index 44fe7fb..9102202 100644 --- a/vendor/prefixed/mcp/sdk/src/Server/Session/SessionInterface.php +++ b/vendor/prefixed/mcp/sdk/src/Server/Session/SessionInterface.php @@ -66,8 +66,4 @@ public function all() : array; * @param array $attributes */ public function hydrate(array $attributes) : void; - /** - * Get the session store instance. - */ - public function getStore() : SessionStoreInterface; } diff --git a/vendor/prefixed/mcp/sdk/src/Server/Session/SessionManager.php b/vendor/prefixed/mcp/sdk/src/Server/Session/SessionManager.php new file mode 100644 index 0000000..99ba7e0 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Server/Session/SessionManager.php @@ -0,0 +1,56 @@ + + */ +class SessionManager implements SessionManagerInterface +{ + public function __construct(private readonly SessionStoreInterface $store, private readonly LoggerInterface $logger = new NullLogger()) + { + } + public function create() : SessionInterface + { + return new Session($this->store, Uuid::v4()); + } + public function createWithId(Uuid $id) : SessionInterface + { + return new Session($this->store, $id); + } + public function exists(Uuid $id) : bool + { + return $this->store->exists($id); + } + public function destroy(Uuid $id) : bool + { + return $this->store->destroy($id); + } + /** + * Run garbage collection on expired sessions. + * Uses the session store's internal TTL configuration. + */ + public function gc() : void + { + if (random_int(0, 100) > 1) { + return; + } + $deletedSessions = $this->store->gc(); + if (!empty($deletedSessions)) { + $this->logger->debug('Garbage collected expired sessions.', ['count' => \count($deletedSessions), 'session_ids' => array_map(static fn(Uuid $id) => $id->toRfc4122(), $deletedSessions)]); + } + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Server/Session/SessionFactoryInterface.php b/vendor/prefixed/mcp/sdk/src/Server/Session/SessionManagerInterface.php similarity index 67% rename from vendor/prefixed/mcp/sdk/src/Server/Session/SessionFactoryInterface.php rename to vendor/prefixed/mcp/sdk/src/Server/Session/SessionManagerInterface.php index 2d8de8e..94c5dc5 100644 --- a/vendor/prefixed/mcp/sdk/src/Server/Session/SessionFactoryInterface.php +++ b/vendor/prefixed/mcp/sdk/src/Server/Session/SessionManagerInterface.php @@ -17,16 +17,25 @@ * * @author Kyrian Obikwelu */ -interface SessionFactoryInterface +interface SessionManagerInterface { /** * Creates a new session with an auto-generated UUID. * This is the standard factory method for creating sessions. */ - public function create(SessionStoreInterface $store) : SessionInterface; + public function create() : SessionInterface; /** * Creates a session with a specific UUID. * Use this when you need to reconstruct a session with a known ID. */ - public function createWithId(Uuid $id, SessionStoreInterface $store) : SessionInterface; + public function createWithId(Uuid $id) : SessionInterface; + /** + * Checks if a session with the given UUID exists. + */ + public function exists(Uuid $id) : bool; + /** + * Destroys the session with the given UUID. + */ + public function destroy(Uuid $id) : bool; + public function gc() : void; } diff --git a/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/Middleware/AuthorizationMiddleware.php b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/Middleware/AuthorizationMiddleware.php new file mode 100644 index 0000000..250c503 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/Middleware/AuthorizationMiddleware.php @@ -0,0 +1,145 @@ + + */ +final class AuthorizationMiddleware implements MiddlewareInterface +{ + private ResponseFactoryInterface $responseFactory; + /** + * @param AuthorizationTokenValidatorInterface $validator Token validator implementation + * @param ProtectedResourceMetadata $resourceMetadata Protected resource metadata object used for challenge hints + * @param ResponseFactoryInterface|null $responseFactory PSR-17 response factory (auto-discovered if null) + */ + public function __construct(private AuthorizationTokenValidatorInterface $validator, private ProtectedResourceMetadata $resourceMetadata, ?ResponseFactoryInterface $responseFactory = null) + { + $this->responseFactory = $responseFactory ?? Psr17FactoryDiscovery::findResponseFactory(); + } + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface + { + $authorization = $request->getHeaderLine('Authorization'); + if ('' === $authorization) { + return $this->buildErrorResponse($request, AuthorizationResult::unauthorized()); + } + $accessToken = $this->parseBearerToken($authorization); + if (null === $accessToken) { + return $this->buildErrorResponse($request, AuthorizationResult::badRequest('invalid_request', 'Malformed Authorization header.')); + } + $result = $this->validator->validate($accessToken); + if (!$result->isAllowed()) { + return $this->buildErrorResponse($request, $result); + } + return $handler->handle($this->applyAttributes($request, $result->getAttributes())); + } + private function buildErrorResponse(ServerRequestInterface $request, AuthorizationResult $result) : ResponseInterface + { + $response = $this->responseFactory->createResponse($result->getStatusCode()); + $header = $this->buildAuthenticateHeader($request, $result); + $response = $response->withHeader('WWW-Authenticate', $header); + return $response; + } + private function buildAuthenticateHeader(ServerRequestInterface $request, AuthorizationResult $result) : string + { + $parts = []; + $parts[] = 'resource_metadata="' . $this->escapeHeaderValue($this->resolveResourceMetadataUrl($request)) . '"'; + $scopes = $this->resolveScopes($result); + if (null !== $scopes) { + $parts[] = 'scope="' . $this->escapeHeaderValue(implode(' ', $scopes)) . '"'; + } + if (null !== $result->getError()) { + $parts[] = 'error="' . $this->escapeHeaderValue($result->getError()) . '"'; + } + if (null !== $result->getErrorDescription()) { + $parts[] = 'error_description="' . $this->escapeHeaderValue($result->getErrorDescription()) . '"'; + } + return 'Bearer ' . implode(', ', $parts); + } + /** + * @return list|null + */ + private function resolveScopes(AuthorizationResult $result) : ?array + { + $scopes = $this->normalizeScopes($result->getScopes()); + if (null !== $scopes) { + return $scopes; + } + return $this->normalizeScopes($this->resourceMetadata->getScopesSupported()); + } + /** + * @param list|null $scopes + * + * @return list|null + */ + private function normalizeScopes(?array $scopes) : ?array + { + if (null === $scopes) { + return null; + } + $normalized = array_values(array_filter(array_map('trim', $scopes), static function (string $scope) : bool { + return '' !== $scope; + })); + return [] === $normalized ? null : $normalized; + } + private function resolveResourceMetadataUrl(ServerRequestInterface $request) : string + { + $metadataPath = $this->resourceMetadata->getPrimaryMetadataPath(); + $uri = $request->getUri(); + $scheme = $uri->getScheme(); + $authority = $uri->getAuthority(); + if ('' === $scheme || '' === $authority) { + throw new RuntimeException('Cannot resolve resource metadata URL: request URI must have scheme and authority'); + } + return $scheme . '://' . $authority . $metadataPath; + } + /** + * @param array $attributes + */ + private function applyAttributes(ServerRequestInterface $request, array $attributes) : ServerRequestInterface + { + foreach ($attributes as $name => $value) { + $request = $request->withAttribute($name, $value); + } + return $request; + } + private function parseBearerToken(string $authorization) : ?string + { + if (!preg_match('/^Bearer\\s+(.+)$/', $authorization, $matches)) { + return null; + } + $token = trim($matches[1]); + return '' === $token ? null : $token; + } + private function escapeHeaderValue(string $value) : string + { + return str_replace(['\\', '"'], ['\\\\', '\\"'], $value); + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/Middleware/ClientRegistrationMiddleware.php b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/Middleware/ClientRegistrationMiddleware.php new file mode 100644 index 0000000..ecaf620 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/Middleware/ClientRegistrationMiddleware.php @@ -0,0 +1,120 @@ +responseFactory = $responseFactory ?? Psr17FactoryDiscovery::findResponseFactory(); + $this->streamFactory = $streamFactory ?? Psr17FactoryDiscovery::findStreamFactory(); + } + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface + { + $path = $request->getUri()->getPath(); + if ('POST' === $request->getMethod() && self::REGISTRATION_PATH === $path) { + return $this->handleRegistration($request); + } + $response = $handler->handle($request); + if ('GET' === $request->getMethod() && '/.well-known/oauth-authorization-server' === $path) { + return $this->enrichAuthServerMetadata($response); + } + return $response; + } + private function handleRegistration(ServerRequestInterface $request) : ResponseInterface + { + $contentType = $request->getHeaderLine('Content-Type'); + if (!str_starts_with($contentType, 'application/json')) { + return $this->jsonResponse(400, ['error' => 'invalid_client_metadata', 'error_description' => 'Content-Type must be application/json.'], ['Cache-Control' => 'no-store']); + } + $body = $request->getBody()->__toString(); + try { + $decoded = json_decode($body, \false, 512, \JSON_THROW_ON_ERROR); + } catch (\JsonException) { + return $this->jsonResponse(400, ['error' => 'invalid_client_metadata', 'error_description' => 'Request body must be valid JSON.'], ['Cache-Control' => 'no-store']); + } + if (!$decoded instanceof \stdClass) { + return $this->jsonResponse(400, ['error' => 'invalid_client_metadata', 'error_description' => 'Request body must be a JSON object.'], ['Cache-Control' => 'no-store']); + } + // Re-decode with assoc=true so nested objects become arrays (safe — already validated above) + /** @var array $data */ + $data = json_decode($body, \true, 512, \JSON_THROW_ON_ERROR); + try { + $result = $this->registrar->register($data); + } catch (ClientRegistrationException $e) { + return $this->jsonResponse(400, ['error' => $e->errorCode, 'error_description' => $e->getMessage()], ['Cache-Control' => 'no-store']); + } + return $this->jsonResponse(201, $result, ['Cache-Control' => 'no-store']); + } + private function enrichAuthServerMetadata(ResponseInterface $response) : ResponseInterface + { + if (200 !== $response->getStatusCode()) { + return $response; + } + $stream = $response->getBody(); + if ($stream->isSeekable()) { + $stream->rewind(); + } + try { + $metadata = json_decode($stream->__toString(), \true, 512, \JSON_THROW_ON_ERROR); + } catch (\JsonException) { + if ($stream->isSeekable()) { + $stream->rewind(); + } + return $response; + } + if (!\is_array($metadata) || [] !== $metadata && array_is_list($metadata)) { + if ($stream->isSeekable()) { + $stream->rewind(); + } + return $response; + } + $metadata['registration_endpoint'] = rtrim($this->localBaseUrl, '/') . self::REGISTRATION_PATH; + return $response->withBody($this->streamFactory->createStream(json_encode($metadata, \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_SLASHES)))->withHeader('Content-Type', 'application/json')->withoutHeader('Content-Length'); + } + /** + * @param array $data + * @param array $extraHeaders + */ + private function jsonResponse(int $status, array $data, array $extraHeaders = []) : ResponseInterface + { + $response = $this->responseFactory->createResponse($status)->withHeader('Content-Type', 'application/json')->withBody($this->streamFactory->createStream(json_encode($data, \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_SLASHES))); + foreach ($extraHeaders as $name => $value) { + if ('' !== $value) { + $response = $response->withHeader($name, $value); + } + } + return $response; + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/Middleware/OAuthProxyMiddleware.php b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/Middleware/OAuthProxyMiddleware.php new file mode 100644 index 0000000..08ccd86 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/Middleware/OAuthProxyMiddleware.php @@ -0,0 +1,187 @@ + + */ +final class OAuthProxyMiddleware implements MiddlewareInterface +{ + private const CLIENT_SECRET_BASIC = 'client_secret_basic'; + private const CLIENT_SECRET_POST = 'client_secret_post'; + private ClientInterface $httpClient; + private RequestFactoryInterface $requestFactory; + private ResponseFactoryInterface $responseFactory; + private StreamFactoryInterface $streamFactory; + /** + * @param string $upstreamIssuer The issuer URL of the upstream OAuth provider + * @param string $localBaseUrl The base URL of this MCP server (e.g., http://localhost:8000) + * @param string|null $clientSecret Optional client secret for confidential clients + * @param OidcDiscoveryInterface $discovery OIDC discovery provider for upstream metadata + */ + public function __construct(private readonly string $upstreamIssuer, private readonly string $localBaseUrl, private readonly OidcDiscoveryInterface $discovery, private readonly ?string $clientSecret = null, ?ClientInterface $httpClient = null, ?RequestFactoryInterface $requestFactory = null, ?ResponseFactoryInterface $responseFactory = null, ?StreamFactoryInterface $streamFactory = null) + { + $this->httpClient = $httpClient ?? Psr18ClientDiscovery::find(); + $this->requestFactory = $requestFactory ?? Psr17FactoryDiscovery::findRequestFactory(); + $this->responseFactory = $responseFactory ?? Psr17FactoryDiscovery::findResponseFactory(); + $this->streamFactory = $streamFactory ?? Psr17FactoryDiscovery::findStreamFactory(); + } + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface + { + $path = $request->getUri()->getPath(); + if ('GET' === $request->getMethod() && '/.well-known/oauth-authorization-server' === $path) { + return $this->createAuthServerMetadataResponse(); + } + if ('GET' === $request->getMethod() && '/authorize' === $path) { + return $this->handleAuthorize($request); + } + if ('POST' === $request->getMethod() && '/token' === $path) { + return $this->handleToken($request); + } + return $handler->handle($request); + } + private function handleAuthorize(ServerRequestInterface $request) : ResponseInterface + { + try { + $authorizationEndpoint = $this->discovery->getAuthorizationEndpoint($this->upstreamIssuer); + } catch (RuntimeException) { + return $this->createErrorResponse(500, 'Upstream authorization endpoint not found'); + } + $rawQueryString = $request->getUri()->getQuery(); + $upstreamUrl = $authorizationEndpoint; + if ('' !== $rawQueryString) { + $upstreamUrl .= '?' . $rawQueryString; + } + return $this->responseFactory->createResponse(302)->withHeader('Location', $upstreamUrl)->withHeader('Cache-Control', 'no-store'); + } + private function handleToken(ServerRequestInterface $request) : ResponseInterface + { + try { + $tokenEndpoint = $this->discovery->getTokenEndpoint($this->upstreamIssuer); + } catch (RuntimeException) { + return $this->createErrorResponse(500, 'Upstream token endpoint not found'); + } + $body = $request->getBody()->__toString(); + parse_str($body, $params); + $upstreamAuthorization = trim($request->getHeaderLine('Authorization')); + if ('' === $upstreamAuthorization) { + $upstreamAuthorization = null; + } + if (null !== $this->clientSecret && !isset($params['client_secret']) && null === $upstreamAuthorization) { + $authMethod = $this->resolveTokenEndpointAuthMethod(); + if (self::CLIENT_SECRET_BASIC === $authMethod) { + $clientId = $params['client_id'] ?? null; + if (\is_string($clientId) && '' !== trim($clientId)) { + $upstreamAuthorization = 'Basic ' . base64_encode(trim($clientId) . ':' . $this->clientSecret); + } else { + $params['client_secret'] = $this->clientSecret; + } + } else { + $params['client_secret'] = $this->clientSecret; + } + } + $body = http_build_query($params); + $upstreamRequest = $this->requestFactory->createRequest('POST', $tokenEndpoint)->withHeader('Content-Type', 'application/x-www-form-urlencoded')->withBody($this->streamFactory->createStream($body)); + if (null !== $upstreamAuthorization) { + $upstreamRequest = $upstreamRequest->withHeader('Authorization', $upstreamAuthorization); + } + try { + $upstreamResponse = $this->httpClient->sendRequest($upstreamRequest); + $responseBody = $upstreamResponse->getBody()->__toString(); + return $this->responseFactory->createResponse($upstreamResponse->getStatusCode())->withHeader('Content-Type', $upstreamResponse->getHeaderLine('Content-Type'))->withHeader('Cache-Control', 'no-store')->withBody($this->streamFactory->createStream($responseBody)); + } catch (ClientExceptionInterface $e) { + return $this->createErrorResponse(502, 'Failed to contact upstream token endpoint: ' . $e->getMessage()); + } + } + private function createAuthServerMetadataResponse() : ResponseInterface + { + try { + $upstreamMetadata = $this->discovery->discover($this->upstreamIssuer); + } catch (RuntimeException) { + return $this->createErrorResponse(500, 'Failed to discover upstream server metadata'); + } + $localBaseUrl = rtrim($this->localBaseUrl, '/'); + $localMetadata = ['issuer' => $localBaseUrl, 'authorization_endpoint' => $localBaseUrl . '/authorize', 'token_endpoint' => $localBaseUrl . '/token', 'response_types_supported' => $upstreamMetadata['response_types_supported'] ?? ['code'], 'grant_types_supported' => $upstreamMetadata['grant_types_supported'] ?? ['authorization_code', 'refresh_token'], 'code_challenge_methods_supported' => $upstreamMetadata['code_challenge_methods_supported'] ?? ['S256']]; + $copyFields = ['scopes_supported', 'token_endpoint_auth_methods_supported', 'jwks_uri']; + foreach ($copyFields as $field) { + if (isset($upstreamMetadata[$field])) { + $localMetadata[$field] = $upstreamMetadata[$field]; + } + } + return $this->responseFactory->createResponse(200)->withHeader('Content-Type', 'application/json')->withHeader('Cache-Control', 'max-age=3600')->withBody($this->streamFactory->createStream(json_encode($localMetadata, \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_SLASHES))); + } + private function createErrorResponse(int $status, string $message) : ResponseInterface + { + $body = json_encode(['error' => 'server_error', 'error_description' => $message]); + return $this->responseFactory->createResponse($status)->withHeader('Content-Type', 'application/json')->withBody($this->streamFactory->createStream($body)); + } + private function resolveTokenEndpointAuthMethod() : string + { + $supportedMethods = $this->getTokenEndpointAuthMethods(); + if (\in_array(self::CLIENT_SECRET_BASIC, $supportedMethods, \true)) { + return self::CLIENT_SECRET_BASIC; + } + if (\in_array(self::CLIENT_SECRET_POST, $supportedMethods, \true)) { + return self::CLIENT_SECRET_POST; + } + return self::CLIENT_SECRET_POST; + } + /** + * @return list + */ + private function getTokenEndpointAuthMethods() : array + { + try { + $metadata = $this->discovery->discover($this->upstreamIssuer); + } catch (RuntimeException) { + return []; + } + $methods = $metadata['token_endpoint_auth_methods_supported'] ?? null; + if (!\is_array($methods)) { + return []; + } + $normalized = []; + foreach ($methods as $method) { + if (!\is_string($method)) { + continue; + } + $method = trim($method); + if ('' === $method) { + continue; + } + $normalized[] = $method; + } + return array_values(array_unique($normalized)); + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/Middleware/OAuthRequestMetaMiddleware.php b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/Middleware/OAuthRequestMetaMiddleware.php new file mode 100644 index 0000000..f7f2932 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/Middleware/OAuthRequestMetaMiddleware.php @@ -0,0 +1,123 @@ + + */ +final class OAuthRequestMetaMiddleware implements MiddlewareInterface +{ + private StreamFactoryInterface $streamFactory; + public function __construct(?StreamFactoryInterface $streamFactory = null) + { + $this->streamFactory = $streamFactory ?? Psr17FactoryDiscovery::findStreamFactory(); + } + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface + { + if ('POST' !== $request->getMethod()) { + return $handler->handle($request); + } + $oauthMeta = $this->extractOAuthAttributes($request); + if ([] === $oauthMeta) { + return $handler->handle($request); + } + $body = $request->getBody()->__toString(); + if ('' === trim($body)) { + return $handler->handle($request); + } + try { + $payload = json_decode($body, \true, 512, \JSON_THROW_ON_ERROR); + } catch (\JsonException) { + return $handler->handle($request); + } + $updatedPayload = $this->injectOauthMeta($payload, $oauthMeta); + if (null === $updatedPayload) { + return $handler->handle($request); + } + try { + $updatedBody = json_encode($updatedPayload, \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_SLASHES); + } catch (\JsonException) { + return $handler->handle($request); + } + $request = $request->withBody($this->streamFactory->createStream($updatedBody)); + return $handler->handle($request); + } + /** + * @return array + */ + private function extractOAuthAttributes(ServerRequestInterface $request) : array + { + $result = []; + foreach ($request->getAttributes() as $key => $value) { + if (\is_string($key) && str_starts_with($key, 'oauth.')) { + $result[$key] = $value; + } + } + return $result; + } + /** + * @param array $oauthMeta + */ + private function injectOauthMeta(mixed $payload, array $oauthMeta) : mixed + { + if (!\is_array($payload)) { + return null; + } + if (array_is_list($payload)) { + $updated = []; + foreach ($payload as $entry) { + if (!\is_array($entry)) { + $updated[] = $entry; + continue; + } + $updated[] = $this->injectIntoMessage($entry, $oauthMeta); + } + return $updated; + } + return $this->injectIntoMessage($payload, $oauthMeta); + } + /** + * @param array $message + * @param array $oauthMeta + * + * @return array + */ + private function injectIntoMessage(array $message, array $oauthMeta) : array + { + $params = $message['params'] ?? []; + if (!\is_array($params)) { + return $message; + } + $meta = $params['_meta'] ?? []; + if (!\is_array($meta)) { + $meta = []; + } + $existingOAuth = $meta['oauth'] ?? []; + if (!\is_array($existingOAuth)) { + $existingOAuth = []; + } + $meta['oauth'] = array_merge($existingOAuth, $oauthMeta); + $params['_meta'] = $meta; + $message['params'] = $params; + return $message; + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/Middleware/ProtectedResourceMetadataMiddleware.php b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/Middleware/ProtectedResourceMetadataMiddleware.php new file mode 100644 index 0000000..1a86031 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/Middleware/ProtectedResourceMetadataMiddleware.php @@ -0,0 +1,51 @@ + + */ +final class ProtectedResourceMetadataMiddleware implements MiddlewareInterface +{ + private ResponseFactoryInterface $responseFactory; + private StreamFactoryInterface $streamFactory; + public function __construct(private readonly ProtectedResourceMetadata $metadata, ?ResponseFactoryInterface $responseFactory = null, ?StreamFactoryInterface $streamFactory = null) + { + $this->responseFactory = $responseFactory ?? Psr17FactoryDiscovery::findResponseFactory(); + $this->streamFactory = $streamFactory ?? Psr17FactoryDiscovery::findStreamFactory(); + } + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface + { + if (!$this->isMetadataRequest($request)) { + return $handler->handle($request); + } + return $this->responseFactory->createResponse(200)->withHeader('Content-Type', 'application/json')->withBody($this->streamFactory->createStream(json_encode($this->metadata, \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_SLASHES))); + } + private function isMetadataRequest(ServerRequestInterface $request) : bool + { + if ('GET' !== $request->getMethod()) { + return \false; + } + return \in_array($request->getUri()->getPath(), $this->metadata->getMetadataPaths(), \true); + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/MiddlewareRequestHandler.php b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/MiddlewareRequestHandler.php index e87fa58..8c5fea9 100644 --- a/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/MiddlewareRequestHandler.php +++ b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/MiddlewareRequestHandler.php @@ -22,20 +22,20 @@ * * @internal */ -class MiddlewareRequestHandler implements RequestHandlerInterface +final class MiddlewareRequestHandler implements RequestHandlerInterface { + private int $index = 0; /** * @param list $middleware */ - public function __construct(private array $middleware, private \Closure $application) + public function __construct(private readonly array $middleware, private readonly \Closure $application) { } public function handle(ServerRequestInterface $request) : ResponseInterface { - $middleware = array_shift($this->middleware); - if (null === $middleware) { + if (!isset($this->middleware[$this->index])) { return ($this->application)($request); } - return $middleware->process($request, $this); + return $this->middleware[$this->index++]->process($request, $this); } } diff --git a/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/AuthorizationResult.php b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/AuthorizationResult.php new file mode 100644 index 0000000..68f060c --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/AuthorizationResult.php @@ -0,0 +1,110 @@ + + */ +final class AuthorizationResult +{ + /** + * @param list|null $scopes Scopes to include in WWW-Authenticate challenge + * @param array $attributes Attributes to attach to the request on success + */ + private function __construct(private readonly bool $allowed, private readonly int $statusCode, private readonly ?string $error, private readonly ?string $errorDescription, private readonly ?array $scopes, private readonly array $attributes) + { + } + /** + * Creates a result indicating access is allowed. + * + * @param array $attributes Attributes to attach to the request (e.g., user_id, scopes) + */ + public static function allow(array $attributes = []) : self + { + return new self(\true, 200, null, null, null, $attributes); + } + /** + * Creates a result indicating the request is unauthorized (401). + * + * Use when no valid credentials are provided or the token is invalid. + * + * @param string|null $error OAuth error code (e.g., "invalid_token") + * @param string|null $errorDescription Human-readable error description + * @param list|null $scopes Required scopes to include in challenge + */ + public static function unauthorized(?string $error = null, ?string $errorDescription = null, ?array $scopes = null) : self + { + return new self(\false, 401, $error, $errorDescription, $scopes, []); + } + /** + * Creates a result indicating the request is forbidden (403). + * + * Use when the token is valid but lacks required permissions/scopes. + * + * @param string|null $error OAuth error code (defaults to "insufficient_scope") + * @param string|null $errorDescription Human-readable error description + * @param list|null $scopes Required scopes to include in challenge + */ + public static function forbidden(?string $error = 'insufficient_scope', ?string $errorDescription = null, ?array $scopes = null) : self + { + return new self(\false, 403, $error ?? 'insufficient_scope', $errorDescription, $scopes, []); + } + /** + * Creates a result indicating a bad request (400). + * + * Use when the Authorization header is malformed. + * + * @param string|null $error OAuth error code (defaults to "invalid_request") + * @param string|null $errorDescription Human-readable error description + */ + public static function badRequest(?string $error = 'invalid_request', ?string $errorDescription = null) : self + { + return new self(\false, 400, $error ?? 'invalid_request', $errorDescription, null, []); + } + public function isAllowed() : bool + { + return $this->allowed; + } + public function getStatusCode() : int + { + return $this->statusCode; + } + public function getError() : ?string + { + return $this->error; + } + public function getErrorDescription() : ?string + { + return $this->errorDescription; + } + /** + * @return list|null + */ + public function getScopes() : ?array + { + return $this->scopes; + } + /** + * @return array + */ + public function getAttributes() : array + { + return $this->attributes; + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/AuthorizationTokenValidatorInterface.php b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/AuthorizationTokenValidatorInterface.php new file mode 100644 index 0000000..8a3257c --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/AuthorizationTokenValidatorInterface.php @@ -0,0 +1,31 @@ + + */ +interface AuthorizationTokenValidatorInterface +{ + /** + * Validates an access token extracted from the Authorization header. + * + * @param string $accessToken The bearer token (without "Bearer " prefix) + * + * @return AuthorizationResult The result of the validation + */ + public function validate(string $accessToken) : AuthorizationResult; +} diff --git a/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/ClientRegistrarInterface.php b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/ClientRegistrarInterface.php new file mode 100644 index 0000000..bdb5a46 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/ClientRegistrarInterface.php @@ -0,0 +1,42 @@ + $registrationRequest Client metadata from the registration request body + * + * @return array Registration response including client_id and optional client_secret + * + * @throws ClientRegistrationException If registration fails (e.g. invalid metadata, storage error). + * The exception message is returned to the client as error_description — + * do not include internal details (database errors, stack traces, etc.). + */ + public function register(array $registrationRequest) : array; +} diff --git a/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/JwksProvider.php b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/JwksProvider.php new file mode 100644 index 0000000..c2a25a9 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/JwksProvider.php @@ -0,0 +1,97 @@ + + */ +class JwksProvider implements JwksProviderInterface +{ + private const CACHE_KEY_PREFIX = 'mcp_jwks_'; + private ClientInterface $httpClient; + private RequestFactoryInterface $requestFactory; + /** + * @param OidcDiscoveryInterface $discovery OIDC discovery provider (required for JWKS URI resolution when $jwksUri is not explicit) + * @param ClientInterface|null $httpClient PSR-18 HTTP client (auto-discovered if null) + * @param RequestFactoryInterface|null $requestFactory PSR-17 request factory (auto-discovered if null) + * @param CacheInterface|null $cache Optional PSR-16 cache + * @param int $cacheTtl JWKS cache TTL in seconds + */ + public function __construct(private readonly OidcDiscoveryInterface $discovery, ?ClientInterface $httpClient = null, ?RequestFactoryInterface $requestFactory = null, private readonly ?CacheInterface $cache = null, private readonly int $cacheTtl = 3600) + { + $this->httpClient = $httpClient ?? Psr18ClientDiscovery::find(); + $this->requestFactory = $requestFactory ?? Psr17FactoryDiscovery::findRequestFactory(); + } + /** + * @return array + */ + public function getJwks(string $issuer, ?string $jwksUri = null) : array + { + $jwksUri ??= $this->discovery->getJwksUri($issuer); + $cacheKey = self::CACHE_KEY_PREFIX . hash('sha256', $jwksUri); + if (null !== $this->cache) { + $cached = $this->cache->get($cacheKey); + if ($this->isJwksValid($cached)) { + /* @var array $cached */ + return $cached; + } + } + $jwks = $this->fetchJwks($jwksUri); + if (!$this->isJwksValid($jwks)) { + throw new RuntimeException(\sprintf('JWKS response from %s has invalid format: expected non-empty "keys" array.', $jwksUri)); + } + if (null !== $this->cache) { + $this->cache->set($cacheKey, $jwks, $this->cacheTtl); + } + return $jwks; + } + /** + * @return array + */ + private function fetchJwks(string $jwksUri) : array + { + $request = $this->requestFactory->createRequest('GET', $jwksUri)->withHeader('Accept', 'application/json'); + try { + $response = $this->httpClient->sendRequest($request); + } catch (ClientExceptionInterface $e) { + throw new RuntimeException(\sprintf('Failed to fetch JWKS from %s: %s', $jwksUri, $e->getMessage()), 0, $e); + } + if (200 !== $response->getStatusCode()) { + throw new RuntimeException(\sprintf('Failed to fetch JWKS from %s: HTTP %d', $jwksUri, $response->getStatusCode())); + } + try { + $data = json_decode($response->getBody()->__toString(), \true, 512, \JSON_THROW_ON_ERROR); + } catch (\JsonException $e) { + throw new RuntimeException(\sprintf('Failed to decode JWKS: %s', $e->getMessage()), 0, $e); + } + if (!\is_array($data)) { + throw new RuntimeException('Invalid JWKS format: expected JSON object.'); + } + return $data; + } + private function isJwksValid(mixed $jwks) : bool + { + if (!\is_array($jwks) || !isset($jwks['keys']) || !\is_array($jwks['keys'])) { + return \false; + } + $nonEmptyKeys = array_filter($jwks['keys'], static fn(mixed $key): bool => \is_array($key) && [] !== $key); + return [] !== $nonEmptyKeys; + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/JwksProviderInterface.php b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/JwksProviderInterface.php new file mode 100644 index 0000000..413e22e --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/JwksProviderInterface.php @@ -0,0 +1,27 @@ + + */ +interface JwksProviderInterface +{ + /** + * @param string $issuer authorization server issuer URL + * @param string|null $jwksUri Optional explicit JWKS URI. If null, implementation may resolve via discovery. + * + * @return array + */ + public function getJwks(string $issuer, ?string $jwksUri = null) : array; +} diff --git a/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/JwtTokenValidator.php b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/JwtTokenValidator.php new file mode 100644 index 0000000..e7f8228 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/JwtTokenValidator.php @@ -0,0 +1,167 @@ + + */ +class JwtTokenValidator implements AuthorizationTokenValidatorInterface +{ + /** + * @param string|list $issuer Expected token issuer(s) (e.g., "https://auth.example.com/realms/mcp") + * @param string|list $audience Expected audience(s) for the token + * @param JwksProviderInterface $jwksProvider JWKS provider + * @param string|null $jwksUri Explicit JWKS URI (auto-discovered from first issuer if null) + * @param list $algorithms Allowed JWT algorithms (default: RS256, RS384, RS512) + * @param string $scopeClaim Claim name for scopes (default: "scope") + */ + public function __construct(private readonly string|array $issuer, private readonly string|array $audience, private readonly JwksProviderInterface $jwksProvider, private readonly ?string $jwksUri = null, private readonly array $algorithms = ['RS256', 'RS384', 'RS512'], private readonly string $scopeClaim = 'scope') + { + if (!class_exists(JWT::class)) { + throw new RuntimeException('For using the JwtTokenValidator, the firebase/php-jwt package is required. Try running "composer require firebase/php-jwt".'); + } + } + public function validate(string $accessToken) : AuthorizationResult + { + try { + /** @var array $claims */ + $claims = (array) JWT::decode($accessToken, $this->getJwks()); + // Validate issuer + if (!$this->validateIssuer($claims)) { + return AuthorizationResult::unauthorized('invalid_token', 'Token issuer mismatch.'); + } + // Validate audience + if (!$this->validateAudience($claims)) { + return AuthorizationResult::unauthorized('invalid_token', 'Token audience mismatch.'); + } + // Build attributes to attach to request + $attributes = ['oauth.claims' => $claims, 'oauth.scopes' => $this->extractScopes($claims)]; + // Add common claims as individual attributes + if (isset($claims['sub'])) { + $attributes['oauth.subject'] = $claims['sub']; + } + if (isset($claims['client_id'])) { + $attributes['oauth.client_id'] = $claims['client_id']; + } + // Add azp (authorized party) for OIDC tokens + if (isset($claims['azp'])) { + $attributes['oauth.authorized_party'] = $claims['azp']; + } + return AuthorizationResult::allow($attributes); + } catch (ExpiredException) { + return AuthorizationResult::unauthorized('invalid_token', 'Token has expired.'); + } catch (SignatureInvalidException) { + return AuthorizationResult::unauthorized('invalid_token', 'Token signature verification failed.'); + } catch (BeforeValidException) { + return AuthorizationResult::unauthorized('invalid_token', 'Token is not yet valid.'); + } catch (\InvalidArgumentException|\UnexpectedValueException|\DomainException $e) { + return AuthorizationResult::unauthorized('invalid_token', 'Token validation failed: ' . $e->getMessage()); + } + } + /** + * Validates a token has the required scopes. + * + * Use this after validation to check specific scope requirements. + * + * @param AuthorizationResult $result The result from validate() + * @param list $requiredScopes Scopes required for this operation + * + * @return AuthorizationResult The original result if scopes are sufficient, forbidden otherwise + */ + public function requireScopes(AuthorizationResult $result, array $requiredScopes) : AuthorizationResult + { + if (!$result->isAllowed()) { + return $result; + } + $tokenScopes = $result->getAttributes()['oauth.scopes'] ?? []; + if (!\is_array($tokenScopes)) { + $tokenScopes = []; + } + foreach ($requiredScopes as $required) { + if (!\in_array($required, $tokenScopes, \true)) { + return AuthorizationResult::forbidden('insufficient_scope', \sprintf('Required scope: %s', $required), $requiredScopes); + } + } + return $result; + } + /** + * @return array + */ + private function getJwks() : array + { + $issuer = \is_array($this->issuer) ? $this->issuer[0] : $this->issuer; + $jwksData = $this->jwksProvider->getJwks($issuer, $this->jwksUri); + /* @var array */ + return JWK::parseKeySet($jwksData, $this->algorithms[0]); + } + /** + * @param array $claims + */ + private function validateAudience(array $claims) : bool + { + if (!isset($claims['aud'])) { + return \false; + } + $tokenAudiences = \is_array($claims['aud']) ? $claims['aud'] : [$claims['aud']]; + $expectedAudiences = \is_array($this->audience) ? $this->audience : [$this->audience]; + foreach ($expectedAudiences as $expected) { + if (\in_array($expected, $tokenAudiences, \true)) { + return \true; + } + } + return \false; + } + /** + * @param array $claims + */ + private function validateIssuer(array $claims) : bool + { + if (!isset($claims['iss'])) { + return \false; + } + $expectedIssuers = \is_array($this->issuer) ? $this->issuer : [$this->issuer]; + return \in_array($claims['iss'], $expectedIssuers, \true); + } + /** + * @param array $claims + * + * @return list + */ + private function extractScopes(array $claims) : array + { + if (!isset($claims[$this->scopeClaim])) { + return []; + } + $scopeValue = $claims[$this->scopeClaim]; + if (\is_array($scopeValue)) { + return array_values(array_filter($scopeValue, 'is_string')); + } + if (\is_string($scopeValue)) { + return array_values(array_filter(explode(' ', $scopeValue))); + } + return []; + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/LenientOidcDiscoveryMetadataPolicy.php b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/LenientOidcDiscoveryMetadataPolicy.php new file mode 100644 index 0000000..f9b9f70 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/LenientOidcDiscoveryMetadataPolicy.php @@ -0,0 +1,42 @@ + + */ +final class LenientOidcDiscoveryMetadataPolicy implements OidcDiscoveryMetadataPolicyInterface +{ + public function isValid(mixed $metadata) : bool + { + if (!\is_array($metadata) || !isset($metadata['authorization_endpoint'], $metadata['token_endpoint'], $metadata['jwks_uri']) || !\is_string($metadata['authorization_endpoint']) || '' === trim($metadata['authorization_endpoint']) || !\is_string($metadata['token_endpoint']) || '' === trim($metadata['token_endpoint']) || !\is_string($metadata['jwks_uri']) || '' === trim($metadata['jwks_uri'])) { + return \false; + } + if (\array_key_exists('code_challenge_methods_supported', $metadata)) { + if (!\is_array($metadata['code_challenge_methods_supported']) || [] === $metadata['code_challenge_methods_supported']) { + return \false; + } + foreach ($metadata['code_challenge_methods_supported'] as $method) { + if (!\is_string($method) || '' === trim($method)) { + return \false; + } + } + } + return \true; + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/OidcDiscovery.php b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/OidcDiscovery.php new file mode 100644 index 0000000..478bf61 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/OidcDiscovery.php @@ -0,0 +1,198 @@ + + */ +class OidcDiscovery implements OidcDiscoveryInterface +{ + private const CACHE_KEY_PREFIX = 'mcp_oidc_discovery_'; + private ClientInterface $httpClient; + private RequestFactoryInterface $requestFactory; + private OidcDiscoveryMetadataPolicyInterface $metadataPolicy; + /** + * @param ClientInterface|null $httpClient PSR-18 HTTP client (auto-discovered if null) + * @param RequestFactoryInterface|null $requestFactory PSR-17 request factory (auto-discovered if null) + * @param CacheInterface|null $cache PSR-16 cache for metadata (optional) + * @param int $cacheTtl Cache TTL in seconds (default: 1 hour) + * @param OidcDiscoveryMetadataPolicyInterface|null $metadataPolicy Metadata validation policy + */ + public function __construct(?ClientInterface $httpClient = null, ?RequestFactoryInterface $requestFactory = null, private readonly ?CacheInterface $cache = null, private readonly int $cacheTtl = 3600, ?OidcDiscoveryMetadataPolicyInterface $metadataPolicy = null) + { + $this->httpClient = $httpClient ?? Psr18ClientDiscovery::find(); + $this->requestFactory = $requestFactory ?? Psr17FactoryDiscovery::findRequestFactory(); + $this->metadataPolicy = $metadataPolicy ?? new StrictOidcDiscoveryMetadataPolicy(); + } + /** + * Gets the JWKS URI from the authorization server metadata. + * + * @param string $issuer The issuer URL + * + * @return string The JWKS URI + * + * @throws RuntimeException If discover fails + */ + public function getJwksUri(string $issuer) : string + { + $metadata = $this->discover($issuer); + return $metadata['jwks_uri']; + } + /** + * Gets the token endpoint from the authorization server metadata. + * + * @param string $issuer The issuer URL + * + * @return string The token endpoint URL + * + * @throws RuntimeException If discover fails + */ + public function getTokenEndpoint(string $issuer) : string + { + $metadata = $this->discover($issuer); + return $metadata['token_endpoint']; + } + /** + * Gets the authorization endpoint from the authorization server metadata. + * + * @param string $issuer The issuer URL + * + * @return string The authorization endpoint URL + * + * @throws RuntimeException If discover fails + */ + public function getAuthorizationEndpoint(string $issuer) : string + { + $metadata = $this->discover($issuer); + return $metadata['authorization_endpoint']; + } + /** + * Discovers authorization server metadata from the issuer URL. + * + * Tries endpoints in priority order per RFC 8414 and OpenID Connect Discovery: + * 1. OAuth 2.0 path insertion: /.well-known/oauth-authorization-server/{path} + * 2. OIDC path insertion: /.well-known/openid-configuration/{path} + * 3. OIDC path appending: {path}/.well-known/openid-configuration + * + * @param string $issuer The issuer URL (e.g., "https://auth.example.com/realms/mcp") + * + * @return array The authorization server metadata + * + * @throws RuntimeException If discovery fails + */ + public function discover(string $issuer) : array + { + $cacheKey = self::CACHE_KEY_PREFIX . hash('sha256', $issuer); + if (null !== $this->cache) { + $cached = $this->cache->get($cacheKey); + if (\is_array($cached)) { + /* @var array $cached */ + return $cached; + } + } + $metadata = $this->fetchMetadata($issuer); + if (null !== $this->cache) { + $this->cache->set($cacheKey, $metadata, $this->cacheTtl); + } + return $metadata; + } + /** + * @return array + */ + private function fetchMetadata(string $issuer) : array + { + $issuer = rtrim($issuer, '/'); + $parsed = parse_url($issuer); + if (\false === $parsed || !isset($parsed['scheme'], $parsed['host'])) { + throw new RuntimeException(\sprintf('Invalid issuer URL: %s', $issuer)); + } + $scheme = $parsed['scheme']; + $host = $parsed['host']; + $port = isset($parsed['port']) ? ':' . $parsed['port'] : ''; + $path = $parsed['path'] ?? ''; + $baseUrl = $scheme . '://' . $host . $port; + // Build discovery URLs in priority order per RFC 8414 Section 3.1 + $discoveryUrls = []; + if ('' !== $path && '/' !== $path) { + // For issuer URLs with path components + // 1. OAuth 2.0 path insertion + $discoveryUrls[] = $baseUrl . '/.well-known/oauth-authorization-server' . $path; + // 2. OIDC path insertion + $discoveryUrls[] = $baseUrl . '/.well-known/openid-configuration' . $path; + // 3. OIDC path appending + $discoveryUrls[] = $issuer . '/.well-known/openid-configuration'; + } else { + // For issuer URLs without path components + $discoveryUrls[] = $baseUrl . '/.well-known/oauth-authorization-server'; + $discoveryUrls[] = $baseUrl . '/.well-known/openid-configuration'; + } + $lastException = null; + foreach ($discoveryUrls as $url) { + try { + $metadata = $this->fetchJson($url); + if (!$this->metadataPolicy->isValid($metadata)) { + throw new RuntimeException(\sprintf('OIDC discovery response from %s has invalid format.', $url)); + } + if (!isset($metadata['issuer']) || !\is_string($metadata['issuer'])) { + throw new RuntimeException(\sprintf('OIDC discovery response from %s is missing required "issuer" field.', $url)); + } + if ($metadata['issuer'] !== $issuer) { + throw new RuntimeException(\sprintf('OIDC discovery issuer mismatch for %s: expected %s, got %s.', $url, $issuer, $metadata['issuer'])); + } + return $metadata; + } catch (RuntimeException $e) { + $lastException = $e; + continue; + } + } + throw new RuntimeException(\sprintf('Failed to discover authorization server metadata for issuer: %s', $issuer), 0, $lastException); + } + /** + * @return array + */ + private function fetchJson(string $url) : array + { + $request = $this->requestFactory->createRequest('GET', $url)->withHeader('Accept', 'application/json'); + try { + $response = $this->httpClient->sendRequest($request); + } catch (ClientExceptionInterface $e) { + throw new RuntimeException(\sprintf('HTTP request to %s failed: %s', $url, $e->getMessage()), 0, $e); + } + if (200 !== $response->getStatusCode()) { + throw new RuntimeException(\sprintf('HTTP request to %s failed with status %d', $url, $response->getStatusCode())); + } + try { + $data = json_decode($response->getBody()->__toString(), \true, 512, \JSON_THROW_ON_ERROR); + } catch (\JsonException $e) { + throw new RuntimeException(\sprintf('Failed to decode JSON from %s: %s', $url, $e->getMessage()), 0, $e); + } + if (!\is_array($data)) { + throw new RuntimeException(\sprintf('Expected JSON object from %s, got %s', $url, \gettype($data))); + } + return $data; + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/OidcDiscoveryInterface.php b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/OidcDiscoveryInterface.php new file mode 100644 index 0000000..9b81152 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/OidcDiscoveryInterface.php @@ -0,0 +1,27 @@ + + */ +interface OidcDiscoveryInterface +{ + /** + * @return array + */ + public function discover(string $issuer) : array; + public function getAuthorizationEndpoint(string $issuer) : string; + public function getTokenEndpoint(string $issuer) : string; + public function getJwksUri(string $issuer) : string; +} diff --git a/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/OidcDiscoveryMetadataPolicyInterface.php b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/OidcDiscoveryMetadataPolicyInterface.php new file mode 100644 index 0000000..ddd28e2 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/OidcDiscoveryMetadataPolicyInterface.php @@ -0,0 +1,21 @@ + + */ +interface OidcDiscoveryMetadataPolicyInterface +{ + public function isValid(mixed $metadata) : bool; +} diff --git a/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/ProtectedResourceMetadata.php b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/ProtectedResourceMetadata.php new file mode 100644 index 0000000..db1bb63 --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/ProtectedResourceMetadata.php @@ -0,0 +1,188 @@ + + */ +final class ProtectedResourceMetadata implements \JsonSerializable +{ + public const DEFAULT_METADATA_PATH = '/.well-known/oauth-protected-resource'; + private const LOCALIZED_HUMAN_READABLE_FIELD_PATTERN = '/^(resource_name|resource_documentation|resource_policy_uri|resource_tos_uri)#[A-Za-z0-9-]+$/'; + /** @var list */ + private array $authorizationServers; + /** @var list|null */ + private ?array $scopesSupported; + /** @var list */ + private array $metadataPaths; + /** @var array */ + private array $localizedHumanReadable; + /** @var array */ + private array $extra; + private ?string $resource; + private ?string $resourceName; + private ?string $resourceDocumentation; + private ?string $resourcePolicyUri; + private ?string $resourceTosUri; + /** + * @param list $authorizationServers + * @param list|null $scopesSupported + * @param array $localizedHumanReadable Locale-specific values, e.g. resource_name#en => "My Resource" + * @param array $extra Additional RFC 9728 metadata fields + * @param list $metadataPaths + */ + public function __construct(array $authorizationServers, ?array $scopesSupported = null, ?string $resource = null, ?string $resourceName = null, ?string $resourceDocumentation = null, ?string $resourcePolicyUri = null, ?string $resourceTosUri = null, array $localizedHumanReadable = [], array $extra = [], array $metadataPaths = [self::DEFAULT_METADATA_PATH]) + { + $this->authorizationServers = $this->normalizeStringList($authorizationServers, 'authorizationServers'); + if ([] === $this->authorizationServers) { + throw new InvalidArgumentException('Protected resource metadata requires at least one authorization server.'); + } + $normalizedScopes = $this->normalizeStringList($scopesSupported ?? [], 'scopesSupported'); + $this->scopesSupported = [] === $normalizedScopes ? null : $normalizedScopes; + $this->resource = $this->normalizeNullableString($resource); + $this->resourceName = $this->normalizeNullableString($resourceName); + $this->resourceDocumentation = $this->normalizeNullableString($resourceDocumentation); + $this->resourcePolicyUri = $this->normalizeNullableString($resourcePolicyUri); + $this->resourceTosUri = $this->normalizeNullableString($resourceTosUri); + $this->localizedHumanReadable = $this->normalizeLocalizedHumanReadable($localizedHumanReadable); + $this->extra = $extra; + $this->metadataPaths = $this->normalizePaths($metadataPaths); + if ([] === $this->metadataPaths) { + throw new InvalidArgumentException('Protected resource metadata requires at least one metadata path.'); + } + } + /** + * @return list + */ + public function getMetadataPaths() : array + { + return $this->metadataPaths; + } + public function getPrimaryMetadataPath() : string + { + return $this->metadataPaths[0]; + } + /** + * @return list|null + */ + public function getScopesSupported() : ?array + { + return $this->scopesSupported; + } + /** + * @return array + */ + public function jsonSerialize() : array + { + $data = ['authorization_servers' => $this->authorizationServers]; + if (null !== $this->scopesSupported) { + $data['scopes_supported'] = $this->scopesSupported; + } + if (null !== $this->resource) { + $data['resource'] = $this->resource; + } + if (null !== $this->resourceName) { + $data['resource_name'] = $this->resourceName; + } + if (null !== $this->resourceDocumentation) { + $data['resource_documentation'] = $this->resourceDocumentation; + } + if (null !== $this->resourcePolicyUri) { + $data['resource_policy_uri'] = $this->resourcePolicyUri; + } + if (null !== $this->resourceTosUri) { + $data['resource_tos_uri'] = $this->resourceTosUri; + } + foreach ($this->localizedHumanReadable as $key => $value) { + $data[$key] = $value; + } + return array_merge($this->extra, $data); + } + /** + * @param list $values + * + * @return list + */ + private function normalizeStringList(array $values, string $parameterName) : array + { + $normalized = []; + foreach ($values as $value) { + if (!\is_string($value)) { + throw new InvalidArgumentException(\sprintf('Protected resource metadata parameter "%s" must contain strings.', $parameterName)); + } + $value = trim($value); + if ('' === $value) { + continue; + } + $normalized[] = $value; + } + return array_values(array_unique($normalized)); + } + private function normalizeNullableString(?string $value) : ?string + { + if (null === $value) { + return null; + } + $value = trim($value); + return '' === $value ? null : $value; + } + /** + * @param list $paths + * + * @return list + */ + private function normalizePaths(array $paths) : array + { + $normalized = []; + foreach ($paths as $path) { + if (!\is_string($path)) { + throw new InvalidArgumentException('Protected resource metadata paths must be strings.'); + } + $path = trim($path); + if ('' === $path) { + continue; + } + if ('/' !== $path[0]) { + $path = '/' . $path; + } + $normalized[] = $path; + } + return array_values(array_unique($normalized)); + } + /** + * @param array $localizedHumanReadable + * + * @return array + */ + private function normalizeLocalizedHumanReadable(array $localizedHumanReadable) : array + { + $normalized = []; + foreach ($localizedHumanReadable as $field => $value) { + if (!\is_string($field) || !preg_match(self::LOCALIZED_HUMAN_READABLE_FIELD_PATTERN, $field)) { + throw new InvalidArgumentException(\sprintf('Invalid localized human-readable field: "%s".', (string) $field)); + } + if (!\is_string($value)) { + throw new InvalidArgumentException(\sprintf('Localized human-readable value for "%s" must be a string.', $field)); + } + $value = trim($value); + if ('' === $value) { + continue; + } + $normalized[$field] = $value; + } + return $normalized; + } +} diff --git a/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/StrictOidcDiscoveryMetadataPolicy.php b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/StrictOidcDiscoveryMetadataPolicy.php new file mode 100644 index 0000000..5da089a --- /dev/null +++ b/vendor/prefixed/mcp/sdk/src/Server/Transport/Http/OAuth/StrictOidcDiscoveryMetadataPolicy.php @@ -0,0 +1,35 @@ + + */ +final class StrictOidcDiscoveryMetadataPolicy implements OidcDiscoveryMetadataPolicyInterface +{ + public function isValid(mixed $metadata) : bool + { + if (!\is_array($metadata) || !isset($metadata['authorization_endpoint'], $metadata['token_endpoint'], $metadata['jwks_uri']) || !\is_string($metadata['authorization_endpoint']) || '' === trim($metadata['authorization_endpoint']) || !\is_string($metadata['token_endpoint']) || '' === trim($metadata['token_endpoint']) || !\is_string($metadata['jwks_uri']) || '' === trim($metadata['jwks_uri']) || !isset($metadata['code_challenge_methods_supported'])) { + return \false; + } + if (!\is_array($metadata['code_challenge_methods_supported']) || [] === $metadata['code_challenge_methods_supported']) { + return \false; + } + foreach ($metadata['code_challenge_methods_supported'] as $method) { + if (!\is_string($method) || '' === trim($method)) { + return \false; + } + } + return \true; + } +} diff --git a/vendor/prefixed/php-http/discovery/src/Composer/Plugin.php b/vendor/prefixed/php-http/discovery/src/Composer/Plugin.php index 1158b01..b8fc277 100644 --- a/vendor/prefixed/php-http/discovery/src/Composer/Plugin.php +++ b/vendor/prefixed/php-http/discovery/src/Composer/Plugin.php @@ -48,7 +48,7 @@ class Plugin implements PluginInterface, EventSubscriberInterface * depending on which one is already installed on the right side. */ private const STICKYNESS_RULES = ['symfony/http-client' => 'symfony/framework-bundle', 'php-http/guzzle7-adapter' => 'guzzlehttp/guzzle:^7', 'php-http/guzzle6-adapter' => 'guzzlehttp/guzzle:^6', 'php-http/guzzle5-adapter' => 'guzzlehttp/guzzle:^5', 'php-http/cakephp-adapter' => 'cakephp/cakephp', 'php-http/react-adapter' => 'react/event-loop', 'php-http/buzz-adapter' => 'kriswallsmith/buzz:^0.15.1', 'php-http/artax-adapter' => 'amphp/artax:^3', 'http-interop/http-factory-guzzle' => 'guzzlehttp/psr7:^1', 'http-interop/http-factory-slim' => 'slim/slim:^3']; - private const INTERFACE_MAP = ['php-http/async-client-implementation' => ['Http\\Client\\HttpAsyncClient'], 'php-http/client-implementation' => ['Http\\Client\\HttpClient'], 'psr/http-client-implementation' => ['Psr\\Http\\Client\\ClientInterface'], 'psr/http-factory-implementation' => ['Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\RequestFactoryInterface', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\ResponseFactoryInterface', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\ServerRequestFactoryInterface', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\StreamFactoryInterface', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\UploadedFileFactoryInterface', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\UriFactoryInterface']]; + private const INTERFACE_MAP = ['php-http/async-client-implementation' => ['Http\\Client\\HttpAsyncClient'], 'php-http/client-implementation' => ['Http\\Client\\HttpClient'], 'psr/http-client-implementation' => ['Matomo\\Dependencies\\McpServer\\Psr\\Http\\Client\\ClientInterface'], 'psr/http-factory-implementation' => ['Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\RequestFactoryInterface', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\ResponseFactoryInterface', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\ServerRequestFactoryInterface', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\StreamFactoryInterface', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\UploadedFileFactoryInterface', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\UriFactoryInterface']]; public static function getSubscribedEvents() : array { return [ScriptEvents::PRE_AUTOLOAD_DUMP => 'preAutoloadDump', ScriptEvents::POST_UPDATE_CMD => 'postUpdate']; diff --git a/vendor/prefixed/php-http/discovery/src/Psr18Client.php b/vendor/prefixed/php-http/discovery/src/Psr18Client.php index e42228d..60dc812 100644 --- a/vendor/prefixed/php-http/discovery/src/Psr18Client.php +++ b/vendor/prefixed/php-http/discovery/src/Psr18Client.php @@ -2,7 +2,7 @@ namespace Matomo\Dependencies\McpServer\Http\Discovery; -use Psr\Http\Client\ClientInterface; +use Matomo\Dependencies\McpServer\Psr\Http\Client\ClientInterface; use Matomo\Dependencies\McpServer\Psr\Http\Message\RequestFactoryInterface; use Matomo\Dependencies\McpServer\Psr\Http\Message\RequestInterface; use Matomo\Dependencies\McpServer\Psr\Http\Message\ResponseFactoryInterface; diff --git a/vendor/prefixed/php-http/discovery/src/Psr18ClientDiscovery.php b/vendor/prefixed/php-http/discovery/src/Psr18ClientDiscovery.php index ce3ee32..b3bc7ef 100644 --- a/vendor/prefixed/php-http/discovery/src/Psr18ClientDiscovery.php +++ b/vendor/prefixed/php-http/discovery/src/Psr18ClientDiscovery.php @@ -4,7 +4,7 @@ use Matomo\Dependencies\McpServer\Http\Discovery\Exception\DiscoveryFailedException; use Matomo\Dependencies\McpServer\Http\Discovery\Exception\NotFoundException as RealNotFoundException; -use Psr\Http\Client\ClientInterface; +use Matomo\Dependencies\McpServer\Psr\Http\Client\ClientInterface; /** * Finds a PSR-18 HTTP Client. * diff --git a/vendor/prefixed/php-http/discovery/src/Strategy/CommonClassesStrategy.php b/vendor/prefixed/php-http/discovery/src/Strategy/CommonClassesStrategy.php index f52e18a..6021f6a 100644 --- a/vendor/prefixed/php-http/discovery/src/Strategy/CommonClassesStrategy.php +++ b/vendor/prefixed/php-http/discovery/src/Strategy/CommonClassesStrategy.php @@ -33,7 +33,7 @@ use Http\Message\UriFactory\SlimUriFactory; use Laminas\Diactoros\Request as DiactorosRequest; use Matomo\Dependencies\McpServer\Nyholm\Psr7\Factory\HttplugFactory as NyholmHttplugFactory; -use Psr\Http\Client\ClientInterface as Psr18Client; +use Matomo\Dependencies\McpServer\Psr\Http\Client\ClientInterface as Psr18Client; use Matomo\Dependencies\McpServer\Psr\Http\Message\RequestFactoryInterface as Psr17RequestFactory; use Slim\Http\Request as SlimRequest; use Symfony\Component\HttpClient\HttplugClient as SymfonyHttplug; diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/README.md b/vendor/prefixed/phpdocumentor/reflection-docblock/README.md index df426a0..9754ba6 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/README.md +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/README.md @@ -71,4 +71,4 @@ $description = (string) $docblock->getDescription(); $description = $docblock->getDescription()->render(); ``` -> For more examples it would be best to review the scripts in the [`/examples` folder](/examples). +> For more examples it would be best to review the scripts in the [`/docs/examples` folder](/docs/examples). diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/composer.json b/vendor/prefixed/phpdocumentor/reflection-docblock/composer.json index 3a0ba65..e0a3e54 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/composer.json +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/composer.json @@ -15,11 +15,11 @@ ], "require": { "php": "^7.4 || ^8.0", - "phpdocumentor\/type-resolver": "^1.7", + "phpdocumentor\/type-resolver": "^2.0", "webmozart\/assert": "^1.9.1 || ^2", "phpdocumentor\/reflection-common": "^2.2", "ext-filter": "*", - "phpstan\/phpdoc-parser": "^1.7|^2.0", + "phpstan\/phpdoc-parser": "^2.0", "doctrine\/deprecations": "^1.1" }, "require-dev": { @@ -29,7 +29,8 @@ "phpstan\/phpstan-mockery": "^1.1", "phpstan\/extension-installer": "^1.1", "phpstan\/phpstan-webmozart-assert": "^1.2", - "psalm\/phar": "^5.26" + "psalm\/phar": "^5.26", + "shipmonk\/dead-code-detector": "^0.5.1" }, "autoload": { "psr-4": { diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php index 4fdc5bf..7a3f307 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php @@ -86,8 +86,9 @@ private function lex(string $contents) : array return [$contents]; } return Utils::pregSplit('/\\{ - # "{@}" is not a valid inline tag. This ensures that we do not treat it as one, but treat it literally. - (?!@\\}) + # "{@}" and "{@*}" are not a valid inline tags. This ensures that we do not treat them as one, but treat + # them literally. + (?!(?:@\\}|@\\*\\}) ) # We want to capture the whole tag line, but without the inline tag delimiters. (\\@ # Match everything up to the next delimiter. diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php index cbc5ea4..6129fcf 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php @@ -15,26 +15,31 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Author; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Covers; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Deprecated; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\AbstractPHPStanFactory; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\ExtendsFactory; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\Factory; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\ImplementsFactory; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\MethodFactory; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\MixinFactory; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\ParamFactory; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyFactory; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyReadFactory; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyWriteFactory; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\ReturnFactory; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\TemplateCovariantFactory; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\TemplateFactory; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\ThrowsFactory; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\VarFactory; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Generic; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\InvalidTag; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Link as LinkTag; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Method; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Mixin; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Param; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Property; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\PropertyRead; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Return_; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\See as SeeTag; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Since; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Source; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\TemplateCovariant; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Throws; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Uses; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Var_; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Version; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\FqsenResolver; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\TypeResolver; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Context as TypeContext; use ReflectionMethod; use ReflectionNamedType; @@ -72,32 +77,10 @@ final class StandardTagFactory implements TagFactory /** PCRE regular expression matching a tag name. */ public const REGEX_TAGNAME = '[\\w\\-\\_\\\\:]+'; /** - * @var array|Factory> An array with a tag as a key, and an + * @var array|Tag|Factory> An array with a tag as a key, and an * FQCN to a class that handles it as an array value. */ - private array $tagHandlerMappings = [ - 'author' => Author::class, - 'covers' => Covers::class, - 'deprecated' => Deprecated::class, - // 'example' => '\phpDocumentor\Reflection\DocBlock\Tags\Example', - 'link' => LinkTag::class, - 'mixin' => Mixin::class, - 'method' => Method::class, - 'param' => Param::class, - 'property-read' => PropertyRead::class, - 'property' => Property::class, - 'property-write' => PropertyWrite::class, - 'return' => Return_::class, - 'see' => SeeTag::class, - 'since' => Since::class, - 'source' => Source::class, - 'template-covariant' => TemplateCovariant::class, - 'throw' => Throws::class, - 'throws' => Throws::class, - 'uses' => Uses::class, - 'var' => Var_::class, - 'version' => Version::class, - ]; + private array $tagHandlerMappings = ['author' => Author::class, 'covers' => Covers::class, 'deprecated' => Deprecated::class, 'link' => LinkTag::class, 'see' => SeeTag::class, 'since' => Since::class, 'source' => Source::class, 'uses' => Uses::class, 'version' => Version::class]; /** * @var array> An array with an annotation as a key, and an * FQCN to a class that handles it as an array value. @@ -114,23 +97,40 @@ final class StandardTagFactory implements TagFactory * services that can be inserted into the Factory Methods of Tag Handlers. */ private array $serviceLocator = []; + private function __construct(FqsenResolver $fqsenResolver) + { + $this->fqsenResolver = $fqsenResolver; + $this->addService($fqsenResolver, FqsenResolver::class); + } /** - * Initialize this tag factory with the means to resolve an FQSEN and optionally a list of tag handlers. - * - * If no tag handlers are provided than the default list in the {@see self::$tagHandlerMappings} property - * is used. + * Initialize this tag factory with the means to resolve an FQSEN. * * @see self::registerTagHandler() to add a new tag handler to the existing default list. - * - * @param array> $tagHandlers */ - public function __construct(FqsenResolver $fqsenResolver, ?array $tagHandlers = null) + public static function createInstance(FqsenResolver $fqsenResolver) : self { - $this->fqsenResolver = $fqsenResolver; - if ($tagHandlers !== null) { - $this->tagHandlerMappings = $tagHandlers; - } - $this->addService($fqsenResolver, FqsenResolver::class); + $tagFactory = new self($fqsenResolver); + $descriptionFactory = new DescriptionFactory($tagFactory); + $typeResolver = new TypeResolver($fqsenResolver); + $phpstanTagFactory = new AbstractPHPStanFactory(new ParamFactory($typeResolver, $descriptionFactory), new VarFactory($typeResolver, $descriptionFactory), new ReturnFactory($typeResolver, $descriptionFactory), new PropertyFactory($typeResolver, $descriptionFactory), new PropertyReadFactory($typeResolver, $descriptionFactory), new PropertyWriteFactory($typeResolver, $descriptionFactory), new MethodFactory($typeResolver, $descriptionFactory), new MixinFactory($typeResolver, $descriptionFactory), new ImplementsFactory($typeResolver, $descriptionFactory), new ExtendsFactory($typeResolver, $descriptionFactory), new TemplateFactory($typeResolver, $descriptionFactory), new TemplateCovariantFactory($typeResolver, $descriptionFactory), new ThrowsFactory($typeResolver, $descriptionFactory)); + $tagFactory->addService($descriptionFactory); + $tagFactory->addService($typeResolver); + $tagFactory->registerTagHandler('param', $phpstanTagFactory); + $tagFactory->registerTagHandler('var', $phpstanTagFactory); + $tagFactory->registerTagHandler('return', $phpstanTagFactory); + $tagFactory->registerTagHandler('property', $phpstanTagFactory); + $tagFactory->registerTagHandler('property-read', $phpstanTagFactory); + $tagFactory->registerTagHandler('property-write', $phpstanTagFactory); + $tagFactory->registerTagHandler('method', $phpstanTagFactory); + $tagFactory->registerTagHandler('mixin', $phpstanTagFactory); + $tagFactory->registerTagHandler('extends', $phpstanTagFactory); + $tagFactory->registerTagHandler('implements', $phpstanTagFactory); + $tagFactory->registerTagHandler('template', $phpstanTagFactory); + $tagFactory->registerTagHandler('template-covariant', $phpstanTagFactory); + $tagFactory->registerTagHandler('template-extends', $phpstanTagFactory); + $tagFactory->registerTagHandler('template-implements', $phpstanTagFactory); + $tagFactory->registerTagHandler('throws', $phpstanTagFactory); + return $tagFactory; } public function create(string $tagLine, ?TypeContext $context = null) : Tag { @@ -204,7 +204,7 @@ private function createTag(string $body, string $name, TypeContext $context) : T /** * Determines the Fully Qualified Class Name of the Factory or Tag (containing a Factory Method `create`). * - * @return class-string|Factory + * @return class-string|Tag|Factory */ private function findHandlerClassName(string $tagName, TypeContext $context) { @@ -261,7 +261,7 @@ private function getArgumentsForParametersFromWiring(array $parameters, array $l * Retrieves a series of ReflectionParameter objects for the static 'create' method of the given * tag handler class name. * - * @param class-string|Factory $handler + * @param class-string|Tag|Factory $handler * * @return ReflectionParameter[] */ diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php index aaaa2eb..b1d4a5f 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php @@ -19,7 +19,7 @@ /** * Reflection class for an {@}author tag in a Docblock. */ -final class Author extends BaseTag implements Factory\StaticMethod +final class Author extends BaseTag { /** @var string register that this is the author tag. */ protected string $name = 'author'; diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php index b1ed239..083c772 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php @@ -23,7 +23,7 @@ /** * Reflection class for a @covers tag in a Docblock. */ -final class Covers extends BaseTag implements Factory\StaticMethod +final class Covers extends BaseTag { protected string $name = 'covers'; private Fqsen $refers; diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php index ec1b4ba..ace0792 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php @@ -19,7 +19,7 @@ /** * Reflection class for a {@}deprecated tag in a Docblock. */ -final class Deprecated extends BaseTag implements Factory\StaticMethod +final class Deprecated extends BaseTag { protected string $name = 'deprecated'; /** diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php index ff3d685..7c77a1a 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php @@ -22,7 +22,7 @@ /** * Reflection class for a {@}example tag in a Docblock. */ -final class Example implements Tag, Factory\StaticMethod +final class Example implements Tag { /** @var string Path to a file to use as an example. May also be an absolute URI. */ private string $filePath; diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Extends_.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Extends_.php index 697dce9..d884b69 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Extends_.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Extends_.php @@ -11,9 +11,7 @@ */ namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags; -use Matomo\Dependencies\McpServer\Doctrine\Deprecations\Deprecation; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Description; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tag; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; /** * Reflection class for a {@}extends tag in a Docblock. @@ -26,14 +24,4 @@ public function __construct(Type $type, ?Description $description = null) $this->type = $type; $this->description = $description; } - /** - * @deprecated Create using static factory is deprecated, - * this method should not be called directly by library consumers - */ - public static function create(string $body) : ?Tag - { - Deprecation::trigger('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', 'Create using static factory is deprecated, this method should not be called directly - by library consumers'); - return null; - } } diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php index af06e4b..99b18ac 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php @@ -17,15 +17,16 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Context as TypeContext; use Matomo\Dependencies\McpServer\PHPStan\PhpDocParser\Lexer\Lexer; use Matomo\Dependencies\McpServer\PHPStan\PhpDocParser\Parser\ConstExprParser; +use Matomo\Dependencies\McpServer\PHPStan\PhpDocParser\Parser\ParserException; use Matomo\Dependencies\McpServer\PHPStan\PhpDocParser\Parser\PhpDocParser; use Matomo\Dependencies\McpServer\PHPStan\PhpDocParser\Parser\TokenIterator; use Matomo\Dependencies\McpServer\PHPStan\PhpDocParser\Parser\TypeParser; use Matomo\Dependencies\McpServer\PHPStan\PhpDocParser\ParserConfig; use RuntimeException; -use function class_exists; -use function ltrim; use function property_exists; use function rtrim; +use function str_replace; +use function trim; /** * Factory class creating tags using phpstan's parser * @@ -42,24 +43,22 @@ class AbstractPHPStanFactory implements Factory private array $factories; public function __construct(PHPStanFactory ...$factories) { - if (class_exists(ParserConfig::class)) { - $config = new ParserConfig(['indexes' => \true, 'lines' => \true]); - $this->lexer = new Lexer($config); - $constParser = new ConstExprParser($config); - $this->parser = new PhpDocParser($config, new TypeParser($config, $constParser), $constParser); - } else { - $this->lexer = new Lexer(\true); - $constParser = new ConstExprParser(\true, \true, ['lines' => \true, 'indexes' => \true]); - $this->parser = new PhpDocParser(new TypeParser($constParser, \true, ['lines' => \true, 'indexes' => \true]), $constParser, \true, \true, ['lines' => \true, 'indexes' => \true], \true); - } + $config = new ParserConfig(['indexes' => \true, 'lines' => \true]); + $this->lexer = new Lexer($config); + $constParser = new ConstExprParser($config); + $this->parser = new PhpDocParser($config, new TypeParser($config, $constParser), $constParser); $this->factories = $factories; } public function create(string $tagLine, ?TypeContext $context = null) : Tag { - $tokens = $this->tokenizeLine($tagLine . "\n"); - $ast = $this->parser->parseTag($tokens); - if (property_exists($ast->value, 'description') === \true) { - $ast->value->setAttribute('description', rtrim($ast->value->description . $tokens->joinUntil(Lexer::TOKEN_END), "\n")); + try { + $tokens = $this->tokenizeLine($tagLine); + $ast = $this->parser->parseTag($tokens); + if (property_exists($ast->value, 'description') === \true) { + $ast->value->setAttribute('description', rtrim($ast->value->description . $tokens->joinUntil(Lexer::TOKEN_END), "\n")); + } + } catch (ParserException $e) { + return InvalidTag::create($tagLine, '')->withError($e); } if ($context === null) { $context = new TypeContext(''); @@ -72,6 +71,8 @@ public function create(string $tagLine, ?TypeContext $context = null) : Tag } } catch (RuntimeException $e) { return InvalidTag::create((string) $ast->value, 'method')->withError($e); + } catch (ParserException $e) { + return InvalidTag::create((string) $ast->value, $ast->name)->withError($e); } return InvalidTag::create((string) $ast->value, $ast->name); } @@ -84,12 +85,15 @@ public function create(string $tagLine, ?TypeContext $context = null) : Tag */ private function tokenizeLine(string $tagLine) : TokenIterator { - $tokens = $this->lexer->tokenize($tagLine); + // Prefix continuation lines with "* ", which is consumed by the phpstan parser as TOKEN_PHPDOC_EOL. + $tagLine = str_replace("\n", "\n* ", $tagLine); + $tokens = $this->lexer->tokenize($tagLine . "\n"); $fixed = []; foreach ($tokens as $token) { - if ($token[1] === Lexer::TOKEN_PHPDOC_EOL && rtrim($token[0], " \t") !== $token[0]) { - $fixed[] = [rtrim($token[Lexer::VALUE_OFFSET], " \t"), Lexer::TOKEN_PHPDOC_EOL, $token[2] ?? 0]; - $fixed[] = [ltrim($token[Lexer::VALUE_OFFSET], "\n\r"), Lexer::TOKEN_HORIZONTAL_WS, ($token[2] ?? 0) + 1]; + if ($token[Lexer::TYPE_OFFSET] === Lexer::TOKEN_PHPDOC_EOL) { + // Strip "* " prefix (and other horizontal whitespace) again so it doesn't and up in the + // description when we joinUntil() in create(). + $fixed[] = [Lexer::VALUE_OFFSET => trim($token[Lexer::VALUE_OFFSET], "* \t"), Lexer::TYPE_OFFSET => $token[Lexer::TYPE_OFFSET], Lexer::LINE_OFFSET => $token[Lexer::LINE_OFFSET] ?? 0]; continue; } $fixed[] = $token; diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MethodFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MethodFactory.php index 0dd8394..0234fd1 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MethodFactory.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MethodFactory.php @@ -34,9 +34,9 @@ public function create(PhpDocTagNode $node, Context $context) : Tag { $tagValue = $node->value; Assert::isInstanceOf($tagValue, MethodTagValueNode::class); - return new Method($tagValue->methodName, [], $this->createReturnType($tagValue, $context), $tagValue->isStatic, $this->descriptionFactory->create($tagValue->description, $context), \false, array_map(function (MethodTagValueParameterNode $param) use($context) { + return new Method($tagValue->methodName, array_map(function (MethodTagValueParameterNode $param) use($context) { return new MethodParameter(trim($param->parameterName, '$'), $param->type === null ? new Mixed_() : $this->typeResolver->createType($param->type, $context), $param->isReference, $param->isVariadic, $param->defaultValue === null ? MethodParameter::NO_DEFAULT_VALUE : (string) $param->defaultValue); - }, $tagValue->parameters)); + }, $tagValue->parameters), $this->createReturnType($tagValue, $context), $tagValue->isStatic, $this->descriptionFactory->create($tagValue->description, $context), \false); } public function supports(PhpDocTagNode $node, Context $context) : bool { diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MethodParameterFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MethodParameterFactory.php index 79f737a..cc96485 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MethodParameterFactory.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MethodParameterFactory.php @@ -31,7 +31,7 @@ public function format($defaultValue) : string { $method = 'format' . ucfirst(gettype($defaultValue)); if (method_exists($this, $method)) { - return ' = ' . $this->{$method}($defaultValue); + return $this->{$method}($defaultValue); } return ''; } diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateExtendsFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MixinFactory.php similarity index 77% rename from vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateExtendsFactory.php rename to vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MixinFactory.php index 091e90a..4845720 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateExtendsFactory.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MixinFactory.php @@ -5,17 +5,17 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\DescriptionFactory; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tag; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\TemplateExtends; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Mixin; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\TypeResolver; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Context; -use Matomo\Dependencies\McpServer\PHPStan\PhpDocParser\Ast\PhpDoc\ExtendsTagValueNode; +use Matomo\Dependencies\McpServer\PHPStan\PhpDocParser\Ast\PhpDoc\MixinTagValueNode; use Matomo\Dependencies\McpServer\PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; use Matomo\Dependencies\McpServer\Webmozart\Assert\Assert; use function is_string; /** * @internal This class is not part of the BC promise of this library. */ -final class TemplateExtendsFactory implements PHPStanFactory +final class MixinFactory implements PHPStanFactory { private DescriptionFactory $descriptionFactory; private TypeResolver $typeResolver; @@ -24,18 +24,18 @@ public function __construct(TypeResolver $typeResolver, DescriptionFactory $desc $this->descriptionFactory = $descriptionFactory; $this->typeResolver = $typeResolver; } - public function supports(PhpDocTagNode $node, Context $context) : bool - { - return $node->value instanceof ExtendsTagValueNode && $node->name === '@template-extends'; - } public function create(PhpDocTagNode $node, Context $context) : Tag { $tagValue = $node->value; - Assert::isInstanceOf($tagValue, ExtendsTagValueNode::class); + Assert::isInstanceOf($tagValue, MixinTagValueNode::class); $description = $tagValue->getAttribute('description'); if (is_string($description) === \false) { $description = $tagValue->description; } - return new TemplateExtends($this->typeResolver->createType($tagValue->type, $context), $this->descriptionFactory->create($description, $context)); + return new Mixin($this->typeResolver->createType($tagValue->type, $context), $this->descriptionFactory->create($description, $context)); + } + public function supports(PhpDocTagNode $node, Context $context) : bool + { + return $node->value instanceof MixinTagValueNode; } } diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ParamFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ParamFactory.php index 5d3b884..9095ce9 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ParamFactory.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ParamFactory.php @@ -3,11 +3,11 @@ declare (strict_types=1); namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory; -use Matomo\Dependencies\McpServer\Doctrine\Deprecations\Deprecation; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\DescriptionFactory; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tag; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\InvalidTag; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Param; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Exception\ParserException; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\TypeResolver; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Context; use Matomo\Dependencies\McpServer\PHPStan\PhpDocParser\Ast\PhpDoc\InvalidTagValueNode; @@ -18,7 +18,6 @@ use Matomo\Dependencies\McpServer\PHPStan\PhpDocParser\Ast\Type\OffsetAccessTypeNode; use Matomo\Dependencies\McpServer\Webmozart\Assert\Assert; use function is_string; -use function sprintf; use function trim; /** * @internal This class is not part of the BC promise of this library. @@ -36,8 +35,7 @@ public function create(PhpDocTagNode $node, Context $context) : Tag { $tagValue = $node->value; if ($tagValue instanceof InvalidTagValueNode) { - Deprecation::trigger('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/362', sprintf('Param tag value "%s" is invalid, falling back to legacy parsing. Please update your docblocks.', $tagValue->value)); - return Param::create($tagValue->value, $this->typeResolver, $this->descriptionFactory, $context); + return InvalidTag::create($tagValue->value, 'param')->withError(ParserException::from($tagValue->exception)); } Assert::isInstanceOfAny($tagValue, [ParamTagValueNode::class, TypelessParamTagValueNode::class]); if (($tagValue->type ?? null) instanceof OffsetAccessTypeNode) { diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php deleted file mode 100644 index 60e3e69..0000000 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php +++ /dev/null @@ -1,23 +0,0 @@ -descriptionFactory = $descriptionFactory; + $this->typeResolver = $typeResolver; + } + public function supports(PhpDocTagNode $node, Context $context) : bool + { + return $node->value instanceof TemplateTagValueNode && $node->name === '@template-covariant'; + } + public function create(PhpDocTagNode $node, Context $context) : Tag + { + $tagValue = $node->value; + Assert::isInstanceOf($tagValue, TemplateTagValueNode::class); + $description = $tagValue->getAttribute('description'); + if (is_string($description) === \false) { + $description = $tagValue->description; + } + return new TemplateCovariant($this->typeResolver->createType(new IdentifierTypeNode($tagValue->name), $context), $this->descriptionFactory->create($description, $context)); + } +} diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateImplementsFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ThrowsFactory.php similarity index 76% rename from vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateImplementsFactory.php rename to vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ThrowsFactory.php index 6c72af3..bc9cc46 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateImplementsFactory.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ThrowsFactory.php @@ -5,17 +5,17 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\DescriptionFactory; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tag; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\TemplateImplements; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Throws; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\TypeResolver; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Context; -use Matomo\Dependencies\McpServer\PHPStan\PhpDocParser\Ast\PhpDoc\ImplementsTagValueNode; use Matomo\Dependencies\McpServer\PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; +use Matomo\Dependencies\McpServer\PHPStan\PhpDocParser\Ast\PhpDoc\ThrowsTagValueNode; use Matomo\Dependencies\McpServer\Webmozart\Assert\Assert; use function is_string; /** * @internal This class is not part of the BC promise of this library. */ -final class TemplateImplementsFactory implements PHPStanFactory +final class ThrowsFactory implements PHPStanFactory { private DescriptionFactory $descriptionFactory; private TypeResolver $typeResolver; @@ -24,18 +24,18 @@ public function __construct(TypeResolver $typeResolver, DescriptionFactory $desc $this->descriptionFactory = $descriptionFactory; $this->typeResolver = $typeResolver; } - public function supports(PhpDocTagNode $node, Context $context) : bool - { - return $node->value instanceof ImplementsTagValueNode && $node->name === '@template-implements'; - } public function create(PhpDocTagNode $node, Context $context) : Tag { $tagValue = $node->value; - Assert::isInstanceOf($tagValue, ImplementsTagValueNode::class); + Assert::isInstanceOf($tagValue, ThrowsTagValueNode::class); $description = $tagValue->getAttribute('description'); if (is_string($description) === \false) { $description = $tagValue->description; } - return new TemplateImplements($this->typeResolver->createType($tagValue->type, $context), $this->descriptionFactory->create($description, $context)); + return new Throws($this->typeResolver->createType($tagValue->type, $context), $this->descriptionFactory->create($description, $context)); + } + public function supports(PhpDocTagNode $node, Context $context) : bool + { + return $node->value instanceof ThrowsTagValueNode; } } diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php index 45cde2f..365d563 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php @@ -21,7 +21,7 @@ /** * Parses a tag definition for a DocBlock. */ -final class Generic extends BaseTag implements Factory\StaticMethod +final class Generic extends BaseTag { /** * Parses a tag and populates the member variables. diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Implements_.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Implements_.php index 81a2442..33a1343 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Implements_.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Implements_.php @@ -11,9 +11,7 @@ */ namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags; -use Matomo\Dependencies\McpServer\Doctrine\Deprecations\Deprecation; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Description; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tag; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; /** * Reflection class for a {@}implements tag in a Docblock. @@ -26,14 +24,4 @@ public function __construct(Type $type, ?Description $description = null) $this->type = $type; $this->description = $description; } - /** - * @deprecated Create using static factory is deprecated, - * this method should not be called directly by library consumers - */ - public static function create(string $body) : ?Tag - { - Deprecation::trigger('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', 'Create using static factory is deprecated, this method should not be called directly - by library consumers'); - return null; - } } diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php index 3317dd0..bf4c752 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php @@ -19,7 +19,7 @@ /** * Reflection class for a {@}link tag in a Docblock. */ -final class Link extends BaseTag implements Factory\StaticMethod +final class Link extends BaseTag { protected string $name = 'link'; private string $link; diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php index 43ffa38..f6b1686 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php @@ -11,32 +11,16 @@ */ namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags; -use InvalidArgumentException; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Description; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Exception\CannotCreateTag; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\TypeResolver; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Context as TypeContext; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Mixed_; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Void_; use Matomo\Dependencies\McpServer\Webmozart\Assert\Assert; -use function array_keys; -use function array_map; -use function explode; use function implode; -use function is_string; -use function preg_match; -use function sort; -use function strpos; -use function substr; -use function trigger_error; -use function trim; -use function var_export; -use const E_USER_DEPRECATED; /** * Reflection class for an {@}method in a Docblock. */ -final class Method extends BaseTag implements Factory\StaticMethod +final class Method extends BaseTag { protected string $name = 'method'; private string $methodName; @@ -46,112 +30,20 @@ final class Method extends BaseTag implements Factory\StaticMethod /** @var MethodParameter[] */ private array $parameters; /** - * @param array> $arguments * @param MethodParameter[] $parameters - * @phpstan-param array $arguments */ - public function __construct(string $methodName, array $arguments = [], ?Type $returnType = null, bool $static = \false, ?Description $description = null, bool $returnsReference = \false, ?array $parameters = null) + public function __construct(string $methodName, array $parameters = [], ?Type $returnType = null, bool $static = \false, ?Description $description = null, bool $returnsReference = \false) { Assert::stringNotEmpty($methodName); if ($returnType === null) { $returnType = new Void_(); } - $arguments = $this->filterArguments($arguments); $this->methodName = $methodName; $this->returnType = $returnType; $this->isStatic = $static; $this->description = $description; $this->returnsReference = $returnsReference; - $this->parameters = $parameters ?? $this->fromLegacyArguments($arguments); - } - /** - * @deprecated Create using static factory is deprecated, - * this method should not be called directly by library consumers - */ - public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : ?self - { - trigger_error('Create using static factory is deprecated, this method should not be called directly - by library consumers', E_USER_DEPRECATED); - Assert::stringNotEmpty($body); - Assert::notNull($typeResolver); - Assert::notNull($descriptionFactory); - // 1. none or more whitespace - // 2. optionally the keyword "static" followed by whitespace - // 3. optionally a word with underscores followed by whitespace : as - // type for the return value - // 4. optionally an ampersand followed or not by whitespace : as - // a reference - // 5. then optionally a word with underscores followed by () and - // whitespace : as method name as used by phpDocumentor - // 6. then a word with underscores, followed by ( and any character - // until a ) and whitespace : as method name with signature - // 7. any remaining text : as description - if (!preg_match('/^ - # Static keyword - # Declares a static method ONLY if type is also present - (?: - (static) - \\s+ - )? - # Return type - (?: - ( - (?:[\\w\\|_\\\\]*\\$this[\\w\\|_\\\\]*) - | - (?: - (?:[\\w\\|_\\\\]+) - # array notation - (?:\\[\\])* - )*+ - ) - \\s+ - )? - # Returns reference - (?: - (&) - \\s* - )? - # Method name - ([\\w_]+) - # Arguments - (?: - \\(([^\\)]*)\\) - )? - \\s* - # Description - (.*) - $/sux', $body, $matches)) { - return null; - } - [, $static, $returnType, $returnsReference, $methodName, $argumentLines, $description] = $matches; - $static = $static === 'static'; - if ($returnType === '') { - $returnType = 'void'; - } - $returnsReference = $returnsReference === '&'; - $returnType = $typeResolver->resolve($returnType, $context); - $description = $descriptionFactory->create($description, $context); - /** @phpstan-var array $arguments */ - $arguments = []; - if ($argumentLines !== '') { - $argumentsExploded = explode(',', $argumentLines); - foreach ($argumentsExploded as $argument) { - $argument = explode(' ', self::stripRestArg(trim($argument)), 2); - if (strpos($argument[0], '$') === 0) { - $argumentName = substr($argument[0], 1); - $argumentType = new Mixed_(); - } else { - $argumentType = $typeResolver->resolve($argument[0], $context); - $argumentName = ''; - if (isset($argument[1])) { - $argument[1] = self::stripRestArg($argument[1]); - $argumentName = substr($argument[1], 1); - } - } - $arguments[] = ['name' => $argumentName, 'type' => $argumentType]; - } - } - return new static($methodName, $arguments, $returnType, $static, $description, $returnsReference); + $this->parameters = $parameters; } /** * Retrieves the method name. @@ -160,19 +52,6 @@ public function getMethodName() : string { return $this->methodName; } - /** - * @deprecated Method deprecated, use {@see self::getParameters()} - * - * @return array> - * @phpstan-return array - */ - public function getArguments() : array - { - trigger_error('Method deprecated, use ::getParameters()', E_USER_DEPRECATED); - return array_map(static function (MethodParameter $methodParameter) { - return ['name' => $methodParameter->getName(), 'type' => $methodParameter->getType()]; - }, $this->parameters); - } /** @return MethodParameter[] */ public function getParameters() : array { @@ -213,50 +92,8 @@ public function __toString() : string $reference = $this->returnsReference ? '&' : ''; return $static . ($returnType !== '' ? ($static !== '' ? ' ' : '') . $returnType : '') . ($methodName !== '' ? ($static !== '' || $returnType !== '' ? ' ' : '') . $reference . $methodName : '') . $argumentStr . ($description !== '' ? ' ' . $description : ''); } - /** - * @param mixed[][]|string[] $arguments - * @phpstan-param array $arguments - * - * @return mixed[][] - * @phpstan-return array - */ - private function filterArguments(array $arguments = []) : array - { - $result = []; - foreach ($arguments as $argument) { - if (is_string($argument)) { - $argument = ['name' => $argument]; - } - if (!isset($argument['type'])) { - $argument['type'] = new Mixed_(); - } - $keys = array_keys($argument); - sort($keys); - if ($keys !== ['name', 'type']) { - throw new InvalidArgumentException('Arguments can only have the "name" and "type" fields, found: ' . var_export($keys, \true)); - } - $result[] = $argument; - } - return $result; - } - private static function stripRestArg(string $argument) : string - { - if (strpos($argument, '...') === 0) { - $argument = trim(substr($argument, 3)); - } - return $argument; - } - /** - * @param array{name: string, type: Type} $arguments - * @phpstan-param array $arguments - * - * @return MethodParameter[] - */ - private function fromLegacyArguments(array $arguments) : array + public static function create(string $body) : void { - trigger_error('Create method parameters via legacy format is deprecated add parameters via the constructor', E_USER_DEPRECATED); - return array_map(static function ($arg) { - return new MethodParameter($arg['name'], $arg['type']); - }, $arguments); + throw new CannotCreateTag('Method tag cannot be created'); } } diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/MethodParameter.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/MethodParameter.php index d0e6f40..8875025 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/MethodParameter.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/MethodParameter.php @@ -58,6 +58,6 @@ public function getDefaultValue() : ?string } public function __toString() : string { - return $this->getType() . ' ' . ($this->isReference() ? '&' : '') . ($this->isVariadic() ? '...' : '') . '$' . $this->getName() . ($this->defaultValue !== self::NO_DEFAULT_VALUE ? (new MethodParameterFactory())->format($this->defaultValue) : ''); + return $this->getType() . ' ' . ($this->isReference() ? '&' : '') . ($this->isVariadic() ? '...' : '') . '$' . $this->getName() . ($this->defaultValue !== self::NO_DEFAULT_VALUE ? ' = ' . (new MethodParameterFactory())->format($this->defaultValue) : ''); } } diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Mixin.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Mixin.php index 9f1e052..6cde8b7 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Mixin.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Mixin.php @@ -12,15 +12,11 @@ namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Description; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\DescriptionFactory; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\TypeResolver; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Context as TypeContext; -use Matomo\Dependencies\McpServer\Webmozart\Assert\Assert; /** * Reflection class for a {@}mixin tag in a Docblock. */ -final class Mixin extends TagWithType implements Factory\StaticMethod +final class Mixin extends TagWithType { public function __construct(Type $type, ?Description $description = null) { @@ -28,13 +24,4 @@ public function __construct(Type $type, ?Description $description = null) $this->type = $type; $this->description = $description; } - public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self - { - Assert::notNull($typeResolver); - Assert::notNull($descriptionFactory); - [$type, $description] = self::extractTypeFromBody($body); - $type = $typeResolver->resolve($type, $context); - $description = $descriptionFactory->create($description, $context); - return new static($type, $description); - } } diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php index bdf797f..7bc16a0 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php @@ -11,24 +11,12 @@ */ namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags; -use Matomo\Dependencies\McpServer\Doctrine\Deprecations\Deprecation; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Description; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\DescriptionFactory; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\TypeResolver; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Context as TypeContext; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Utils; -use Matomo\Dependencies\McpServer\Webmozart\Assert\Assert; -use function array_shift; -use function array_unshift; -use function implode; -use function strpos; -use function substr; -use const PREG_SPLIT_DELIM_CAPTURE; /** * Reflection class for the {@}param tag in a Docblock. */ -final class Param extends TagWithType implements Factory\StaticMethod +final class Param extends TagWithType { private ?string $variableName = null; /** @var bool determines whether this is a variadic argument */ @@ -44,54 +32,6 @@ public function __construct(?string $variableName, ?Type $type = null, bool $isV $this->description = $description; $this->isReference = $isReference; } - /** - * @deprecated Create using static factory is deprecated, - * this method should not be called directly by library consumers - */ - public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self - { - Deprecation::triggerIfCalledFromOutside('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', 'Create using static factory is deprecated, this method should not be called directly - by library consumers'); - Assert::stringNotEmpty($body); - Assert::notNull($typeResolver); - Assert::notNull($descriptionFactory); - [$firstPart, $body] = self::extractTypeFromBody($body); - $type = null; - $parts = Utils::pregSplit('/(\\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE); - $variableName = ''; - $isVariadic = \false; - $isReference = \false; - // if the first item that is encountered is not a variable; it is a type - if ($firstPart && !self::strStartsWithVariable($firstPart)) { - $type = $typeResolver->resolve($firstPart, $context); - } else { - // first part is not a type; we should prepend it to the parts array for further processing - array_unshift($parts, $firstPart); - } - // if the next item starts with a $ or ...$ or &$ or &...$ it must be the variable name - if (isset($parts[0]) && self::strStartsWithVariable($parts[0])) { - $variableName = array_shift($parts); - if ($type) { - array_shift($parts); - } - Assert::notNull($variableName); - if (strpos($variableName, '$') === 0) { - $variableName = substr($variableName, 1); - } elseif (strpos($variableName, '&$') === 0) { - $isReference = \true; - $variableName = substr($variableName, 2); - } elseif (strpos($variableName, '...$') === 0) { - $isVariadic = \true; - $variableName = substr($variableName, 4); - } elseif (strpos($variableName, '&...$') === 0) { - $isVariadic = \true; - $isReference = \true; - $variableName = substr($variableName, 5); - } - } - $description = $descriptionFactory->create(implode('', $parts), $context); - return new static($variableName, $type, $isVariadic, $description, $isReference); - } /** * Returns the variable's name. */ @@ -131,8 +71,4 @@ public function __toString() : string $type = (string) $this->type; return $type . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '') . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : ''); } - private static function strStartsWithVariable(string $str) : bool - { - return strpos($str, '$') === 0 || strpos($str, '...$') === 0 || strpos($str, '&$') === 0 || strpos($str, '&...$') === 0; - } } diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php index 8394568..dc1c009 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php @@ -11,24 +11,13 @@ */ namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags; -use Matomo\Dependencies\McpServer\Doctrine\Deprecations\Deprecation; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Description; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\DescriptionFactory; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\TypeResolver; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Context as TypeContext; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Utils; use Matomo\Dependencies\McpServer\Webmozart\Assert\Assert; -use function array_shift; -use function array_unshift; -use function implode; -use function strpos; -use function substr; -use const PREG_SPLIT_DELIM_CAPTURE; /** * Reflection class for a {@}property tag in a Docblock. */ -final class Property extends TagWithType implements Factory\StaticMethod +final class Property extends TagWithType { protected ?string $variableName = null; public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null) @@ -39,40 +28,6 @@ public function __construct(?string $variableName, ?Type $type = null, ?Descript $this->type = $type; $this->description = $description; } - /** - * @deprecated Create using static factory is deprecated, - * this method should not be called directly by library consumers - */ - public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self - { - Deprecation::triggerIfCalledFromOutside('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', 'Create using static factory is deprecated, this method should not be called directly - by library consumers'); - Assert::stringNotEmpty($body); - Assert::notNull($typeResolver); - Assert::notNull($descriptionFactory); - [$firstPart, $body] = self::extractTypeFromBody($body); - $type = null; - $parts = Utils::pregSplit('/(\\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE); - $variableName = ''; - // if the first item that is encountered is not a variable; it is a type - if ($firstPart && $firstPart[0] !== '$') { - $type = $typeResolver->resolve($firstPart, $context); - } else { - // first part is not a type; we should prepend it to the parts array for further processing - array_unshift($parts, $firstPart); - } - // if the next item starts with a $ it must be the variable name - if (isset($parts[0]) && strpos($parts[0], '$') === 0) { - $variableName = array_shift($parts); - if ($type) { - array_shift($parts); - } - Assert::notNull($variableName); - $variableName = substr($variableName, 1); - } - $description = $descriptionFactory->create(implode('', $parts), $context); - return new static($variableName, $type, $description); - } /** * Returns the variable's name. */ diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php index fa65fe9..2d074a9 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php @@ -11,24 +11,13 @@ */ namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags; -use Matomo\Dependencies\McpServer\Doctrine\Deprecations\Deprecation; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Description; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\DescriptionFactory; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\TypeResolver; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Context as TypeContext; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Utils; use Matomo\Dependencies\McpServer\Webmozart\Assert\Assert; -use function array_shift; -use function array_unshift; -use function implode; -use function strpos; -use function substr; -use const PREG_SPLIT_DELIM_CAPTURE; /** * Reflection class for a {@}property-read tag in a Docblock. */ -final class PropertyRead extends TagWithType implements Factory\StaticMethod +final class PropertyRead extends TagWithType { protected ?string $variableName = null; public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null) @@ -39,40 +28,6 @@ public function __construct(?string $variableName, ?Type $type = null, ?Descript $this->type = $type; $this->description = $description; } - /** - * @deprecated Create using static factory is deprecated, - * this method should not be called directly by library consumers - */ - public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self - { - Deprecation::triggerIfCalledFromOutside('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', 'Create using static factory is deprecated, this method should not be called directly - by library consumers'); - Assert::stringNotEmpty($body); - Assert::notNull($typeResolver); - Assert::notNull($descriptionFactory); - [$firstPart, $body] = self::extractTypeFromBody($body); - $type = null; - $parts = Utils::pregSplit('/(\\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE); - $variableName = ''; - // if the first item that is encountered is not a variable; it is a type - if ($firstPart && $firstPart[0] !== '$') { - $type = $typeResolver->resolve($firstPart, $context); - } else { - // first part is not a type; we should prepend it to the parts array for further processing - array_unshift($parts, $firstPart); - } - // if the next item starts with a $ it must be the variable name - if (isset($parts[0]) && strpos($parts[0], '$') === 0) { - $variableName = array_shift($parts); - if ($type) { - array_shift($parts); - } - Assert::notNull($variableName); - $variableName = substr($variableName, 1); - } - $description = $descriptionFactory->create(implode('', $parts), $context); - return new static($variableName, $type, $description); - } /** * Returns the variable's name. */ diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php index 9fcae62..70eacc8 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php @@ -11,24 +11,13 @@ */ namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags; -use Matomo\Dependencies\McpServer\Doctrine\Deprecations\Deprecation; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Description; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\DescriptionFactory; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\TypeResolver; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Context as TypeContext; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Utils; use Matomo\Dependencies\McpServer\Webmozart\Assert\Assert; -use function array_shift; -use function array_unshift; -use function implode; -use function strpos; -use function substr; -use const PREG_SPLIT_DELIM_CAPTURE; /** * Reflection class for a {@}property-write tag in a Docblock. */ -final class PropertyWrite extends TagWithType implements Factory\StaticMethod +final class PropertyWrite extends TagWithType { protected string $variableName; public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null) @@ -39,40 +28,6 @@ public function __construct(?string $variableName, ?Type $type = null, ?Descript $this->type = $type; $this->description = $description; } - /** - * @deprecated Create using static factory is deprecated, - * this method should not be called directly by library consumers - */ - public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self - { - Deprecation::triggerIfCalledFromOutside('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', 'Create using static factory is deprecated, this method should not be called directly - by library consumers'); - Assert::stringNotEmpty($body); - Assert::notNull($typeResolver); - Assert::notNull($descriptionFactory); - [$firstPart, $body] = self::extractTypeFromBody($body); - $type = null; - $parts = Utils::pregSplit('/(\\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE); - $variableName = ''; - // if the first item that is encountered is not a variable; it is a type - if ($firstPart && $firstPart[0] !== '$') { - $type = $typeResolver->resolve($firstPart, $context); - } else { - // first part is not a type; we should prepend it to the parts array for further processing - array_unshift($parts, $firstPart); - } - // if the next item starts with a $ it must be the variable name - if (isset($parts[0]) && strpos($parts[0], '$') === 0) { - $variableName = array_shift($parts); - if ($type) { - array_shift($parts); - } - Assert::notNull($variableName); - $variableName = substr($variableName, 1); - } - $description = $descriptionFactory->create(implode('', $parts), $context); - return new static($variableName, $type, $description); - } /** * Returns the variable's name. */ diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php index 859599a..f4fbf35 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php @@ -11,17 +11,12 @@ */ namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags; -use Matomo\Dependencies\McpServer\Doctrine\Deprecations\Deprecation; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Description; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\DescriptionFactory; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\TypeResolver; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Context as TypeContext; -use Matomo\Dependencies\McpServer\Webmozart\Assert\Assert; /** * Reflection class for a {@}return tag in a Docblock. */ -final class Return_ extends TagWithType implements Factory\StaticMethod +final class Return_ extends TagWithType { public function __construct(Type $type, ?Description $description = null) { @@ -29,19 +24,4 @@ public function __construct(Type $type, ?Description $description = null) $this->type = $type; $this->description = $description; } - /** - * @deprecated Create using static factory is deprecated, - * this method should not be called directly by library consumers - */ - public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self - { - Deprecation::triggerIfCalledFromOutside('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', 'Create using static factory is deprecated, this method should not be called directly - by library consumers'); - Assert::notNull($typeResolver); - Assert::notNull($descriptionFactory); - [$type, $description] = self::extractTypeFromBody($body); - $type = $typeResolver->resolve($type, $context); - $description = $descriptionFactory->create($description, $context); - return new static($type, $description); - } } diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php index dc190dc..39ac6df 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php @@ -27,7 +27,7 @@ /** * Reflection class for an {@}see tag in a Docblock. */ -final class See extends BaseTag implements Factory\StaticMethod +final class See extends BaseTag { protected string $name = 'see'; protected Reference $refers; diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php index 8e40cd7..ac99cd0 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php @@ -19,7 +19,7 @@ /** * Reflection class for a {@}since tag in a Docblock. */ -final class Since extends BaseTag implements Factory\StaticMethod +final class Since extends BaseTag { protected string $name = 'since'; /** diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php index ec4223c..ce20a40 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php @@ -19,7 +19,7 @@ /** * Reflection class for a {@}source tag in a Docblock. */ -final class Source extends BaseTag implements Factory\StaticMethod +final class Source extends BaseTag { protected string $name = 'source'; /** @var int The starting line, relative to the structural element's location. */ diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TagWithType.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TagWithType.php index 1e35474..9bd209c 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TagWithType.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TagWithType.php @@ -11,13 +11,9 @@ */ namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags; -use InvalidArgumentException; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tag; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Exception\CannotCreateTag; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; -use function in_array; -use function sprintf; -use function strlen; -use function substr; -use function trim; abstract class TagWithType extends BaseTag { /** @var ?Type */ @@ -29,33 +25,9 @@ public function getType() : ?Type { return $this->type; } - /** - * @return string[] - */ - protected static function extractTypeFromBody(string $body) : array + public static final function create(string $body) : Tag { - $type = ''; - $nestingLevel = 0; - for ($i = 0, $iMax = strlen($body); $i < $iMax; $i++) { - $character = $body[$i]; - if ($nestingLevel === 0 && trim($character) === '') { - break; - } - $type .= $character; - if (in_array($character, ['<', '(', '[', '{'])) { - $nestingLevel++; - continue; - } - if (in_array($character, ['>', ')', ']', '}'])) { - $nestingLevel--; - continue; - } - } - if ($nestingLevel < 0 || $nestingLevel > 0) { - throw new InvalidArgumentException(sprintf('Could not find type in %s, please check for malformed notations', $body)); - } - $description = trim(substr($body, strlen($type))); - return [$type, $description]; + throw new CannotCreateTag('Typed tag cannot be created'); } public function __toString() : string { diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Template.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Template.php index a5a812c..709a70a 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Template.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Template.php @@ -11,9 +11,9 @@ */ namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags; -use Matomo\Dependencies\McpServer\Doctrine\Deprecations\Deprecation; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Description; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tag; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Exception\CannotCreateTag; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; /** * Reflection class for a {@}template tag in a Docblock. @@ -40,9 +40,7 @@ public function __construct(string $templateName, ?Type $bound = null, ?Type $de */ public static function create(string $body) : ?Tag { - Deprecation::trigger('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', 'Create using static factory is deprecated, this method should not be called directly - by library consumers'); - return null; + throw new CannotCreateTag('Template tag cannot be created'); } public function getTemplateName() : string { diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TemplateCovariant.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TemplateCovariant.php index 9c826bc..9370531 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TemplateCovariant.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TemplateCovariant.php @@ -12,15 +12,11 @@ namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Description; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\DescriptionFactory; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\TypeResolver; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Context as TypeContext; -use Matomo\Dependencies\McpServer\Webmozart\Assert\Assert; /** * Reflection class for a {@}template-covariant tag in a Docblock. */ -final class TemplateCovariant extends TagWithType implements Factory\StaticMethod +final class TemplateCovariant extends TagWithType { public function __construct(Type $type, ?Description $description = null) { @@ -28,13 +24,4 @@ public function __construct(Type $type, ?Description $description = null) $this->type = $type; $this->description = $description; } - public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self - { - Assert::notNull($typeResolver); - Assert::notNull($descriptionFactory); - [$type, $description] = self::extractTypeFromBody($body); - $type = $typeResolver->resolve($type, $context); - $description = $descriptionFactory->create($description, $context); - return new static($type, $description); - } } diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php index 07dcae2..1b8bc78 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php @@ -12,15 +12,11 @@ namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Description; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\DescriptionFactory; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\TypeResolver; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Context as TypeContext; -use Matomo\Dependencies\McpServer\Webmozart\Assert\Assert; /** * Reflection class for a {@}throws tag in a Docblock. */ -final class Throws extends TagWithType implements Factory\StaticMethod +final class Throws extends TagWithType { public function __construct(Type $type, ?Description $description = null) { @@ -28,13 +24,4 @@ public function __construct(Type $type, ?Description $description = null) $this->type = $type; $this->description = $description; } - public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self - { - Assert::notNull($typeResolver); - Assert::notNull($descriptionFactory); - [$type, $description] = self::extractTypeFromBody($body); - $type = $typeResolver->resolve($type, $context); - $description = $descriptionFactory->create($description, $context); - return new static($type, $description); - } } diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php index 479dc6b..46a0a7a 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php @@ -23,7 +23,7 @@ /** * Reflection class for a {@}uses tag in a Docblock. */ -final class Uses extends BaseTag implements Factory\StaticMethod +final class Uses extends BaseTag { protected string $name = 'uses'; protected Fqsen $refers; diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php index 42dafde..c08b3dd 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php @@ -11,24 +11,13 @@ */ namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags; -use Matomo\Dependencies\McpServer\Doctrine\Deprecations\Deprecation; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Description; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\DescriptionFactory; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\TypeResolver; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Context as TypeContext; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Utils; use Matomo\Dependencies\McpServer\Webmozart\Assert\Assert; -use function array_shift; -use function array_unshift; -use function implode; -use function strpos; -use function substr; -use const PREG_SPLIT_DELIM_CAPTURE; /** * Reflection class for a {@}var tag in a Docblock. */ -final class Var_ extends TagWithType implements Factory\StaticMethod +final class Var_ extends TagWithType { protected ?string $variableName = ''; public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null) @@ -39,40 +28,6 @@ public function __construct(?string $variableName, ?Type $type = null, ?Descript $this->type = $type; $this->description = $description; } - /** - * @deprecated Create using static factory is deprecated, - * this method should not be called directly by library consumers - */ - public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self - { - Deprecation::triggerIfCalledFromOutside('phpdocumentor/reflection-docblock', 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', 'Create using static factory is deprecated, this method should not be called directly - by library consumers'); - Assert::stringNotEmpty($body); - Assert::notNull($typeResolver); - Assert::notNull($descriptionFactory); - [$firstPart, $body] = self::extractTypeFromBody($body); - $parts = Utils::pregSplit('/(\\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE); - $type = null; - $variableName = ''; - // if the first item that is encountered is not a variable; it is a type - if ($firstPart && $firstPart[0] !== '$') { - $type = $typeResolver->resolve($firstPart, $context); - } else { - // first part is not a type; we should prepend it to the parts array for further processing - array_unshift($parts, $firstPart); - } - // if the next item starts with a $ it must be the variable name - if (isset($parts[0]) && strpos($parts[0], '$') === 0) { - $variableName = array_shift($parts); - if ($type) { - array_shift($parts); - } - Assert::notNull($variableName); - $variableName = substr($variableName, 1); - } - $description = $descriptionFactory->create(implode('', $parts), $context); - return new static($variableName, $type, $description); - } /** * Returns the variable's name. */ diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php index f69f524..1b239d5 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php @@ -19,7 +19,7 @@ /** * Reflection class for a {@}version tag in a Docblock. */ -final class Version extends BaseTag implements Factory\StaticMethod +final class Version extends BaseTag { protected string $name = 'version'; /** diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlockFactory.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlockFactory.php index 900e4af..a7ecea2 100644 --- a/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlockFactory.php +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/DocBlockFactory.php @@ -17,20 +17,7 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\StandardTagFactory; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tag; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\TagFactory; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\AbstractPHPStanFactory; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\ExtendsFactory; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\Factory; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\ImplementsFactory; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\MethodFactory; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\ParamFactory; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyFactory; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyReadFactory; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyWriteFactory; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\ReturnFactory; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\TemplateExtendsFactory; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\TemplateFactory; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\TemplateImplementsFactory; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\DocBlock\Tags\Factory\VarFactory; use Matomo\Dependencies\McpServer\Webmozart\Assert\Assert; use function array_shift; use function count; @@ -63,24 +50,8 @@ public function __construct(DescriptionFactory $descriptionFactory, TagFactory $ public static function createInstance(array $additionalTags = []) : DocBlockFactoryInterface { $fqsenResolver = new FqsenResolver(); - $tagFactory = new StandardTagFactory($fqsenResolver); + $tagFactory = StandardTagFactory::createInstance($fqsenResolver); $descriptionFactory = new DescriptionFactory($tagFactory); - $typeResolver = new TypeResolver($fqsenResolver); - $phpstanTagFactory = new AbstractPHPStanFactory(new ParamFactory($typeResolver, $descriptionFactory), new VarFactory($typeResolver, $descriptionFactory), new ReturnFactory($typeResolver, $descriptionFactory), new PropertyFactory($typeResolver, $descriptionFactory), new PropertyReadFactory($typeResolver, $descriptionFactory), new PropertyWriteFactory($typeResolver, $descriptionFactory), new MethodFactory($typeResolver, $descriptionFactory), new ImplementsFactory($typeResolver, $descriptionFactory), new ExtendsFactory($typeResolver, $descriptionFactory), new TemplateFactory($typeResolver, $descriptionFactory), new TemplateImplementsFactory($typeResolver, $descriptionFactory), new TemplateExtendsFactory($typeResolver, $descriptionFactory)); - $tagFactory->addService($descriptionFactory); - $tagFactory->addService($typeResolver); - $tagFactory->registerTagHandler('param', $phpstanTagFactory); - $tagFactory->registerTagHandler('var', $phpstanTagFactory); - $tagFactory->registerTagHandler('return', $phpstanTagFactory); - $tagFactory->registerTagHandler('property', $phpstanTagFactory); - $tagFactory->registerTagHandler('property-read', $phpstanTagFactory); - $tagFactory->registerTagHandler('property-write', $phpstanTagFactory); - $tagFactory->registerTagHandler('method', $phpstanTagFactory); - $tagFactory->registerTagHandler('extends', $phpstanTagFactory); - $tagFactory->registerTagHandler('implements', $phpstanTagFactory); - $tagFactory->registerTagHandler('template', $phpstanTagFactory); - $tagFactory->registerTagHandler('template-extends', $phpstanTagFactory); - $tagFactory->registerTagHandler('template-implements', $phpstanTagFactory); $docBlockFactory = new self($descriptionFactory, $tagFactory); foreach ($additionalTags as $tagName => $tagHandler) { $docBlockFactory->registerTagHandler($tagName, $tagHandler); diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/Exception/CannotCreateTag.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/Exception/CannotCreateTag.php new file mode 100644 index 0000000..4de0de7 --- /dev/null +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/Exception/CannotCreateTag.php @@ -0,0 +1,9 @@ +getMessage(), 0, $exception); + } +} diff --git a/vendor/prefixed/phpdocumentor/reflection-docblock/src/Exception/ReflectionDocblockException.php b/vendor/prefixed/phpdocumentor/reflection-docblock/src/Exception/ReflectionDocblockException.php new file mode 100644 index 0000000..3f9f27b --- /dev/null +++ b/vendor/prefixed/phpdocumentor/reflection-docblock/src/Exception/ReflectionDocblockException.php @@ -0,0 +1,9 @@ + :php:class:`phpDocumentor\Reflection\PseudoTypes\InterfaceString` +- ``phpDocumentor\Reflection\Types\ClassString`` => :php:class:`phpDocumentor\Reflection\PseudoTypes\ClassString` +- ``phpDocumentor\Reflection\Types\ArrayKey`` => :php:class:`phpDocumentor\Reflection\PseudoTypes\ArrayKey` +- ``phpDocumentor\Reflection\Types\True_`` => :php:class:`phpDocumentor\Reflection\PseudoTypes\True_` +- ``phpDocumentor\Reflection\Types\False_`` => :php:class:`phpDocumentor\Reflection\PseudoTypes\False_` + +Replaced classes +----------------- + +- ``phpDocumentor\Reflection\Types\Collection`` => :php:class:`phpDocumentor\Reflection\PseudoTypes\Generic` + +Since the introduction of generics in PHP this library was not capable of parsing them correctly. The old Collection +was blocking the use of generics. The new Generic type is a representation of generics like supported in the eco system. + +Changed implementations +----------------------- + +:php:class:`phpDocumentor\Reflection\PseudoTypes\InterfaceString`, :php:class:`phpDocumentor\Reflection\PseudoTypes\ClassString` and +:php:class:`phpDocumentor\Reflection\PseudoTypes\TraitString` are no longer returning a :php:class:`phpDocumentor\Reflection\Fqsen` since +support for generics these classes can have type arguments like any other generic. + diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/ArrayKey.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ArrayKey.php similarity index 69% rename from vendor/prefixed/phpdocumentor/type-resolver/src/Types/ArrayKey.php rename to vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ArrayKey.php index abf1ae4..2687482 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/ArrayKey.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ArrayKey.php @@ -9,14 +9,16 @@ * * @link http://phpdoc.org */ -namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types; +namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\PseudoTypes; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\PseudoType; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\AggregatedType; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Compound; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Integer; +use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\String_; /** - * Value Object representing a array-key Type. - * - * A array-key Type is the supertype (but not a union) of int and string. + * Value Object representing the type `array-key`. * * @psalm-immutable */ diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ArrayShape.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ArrayShape.php index ac4038b..11f5fd4 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ArrayShape.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ArrayShape.php @@ -15,16 +15,16 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\PseudoType; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Array_; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\ArrayKey; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Mixed_; use function implode; /** @psalm-immutable */ -class ArrayShape implements PseudoType +class ArrayShape extends Array_ implements PseudoType { /** @var ArrayShapeItem[] */ private $items; public function __construct(ArrayShapeItem ...$items) { + parent::__construct(new Mixed_(), new ArrayKey()); $this->items = $items; } /** diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/CallableArray.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/CallableArray.php new file mode 100644 index 0000000..e75c702 --- /dev/null +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/CallableArray.php @@ -0,0 +1,38 @@ +fqsen = $fqsen; + $this->genericType = $genericType; } public function underlyingType() : Type { return new String_(); } - /** - * Returns the FQSEN associated with this object. - */ - public function getFqsen() : ?Fqsen + public function getGenericType() : ?Type { - return $this->fqsen; + return $this->genericType; } /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string { - if ($this->fqsen === null) { + if ($this->genericType === null) { return 'class-string'; } - return 'class-string<' . (string) $this->fqsen . '>'; + return 'class-string<' . (string) $this->genericType . '>'; } } diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ClosedResource.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ClosedResource.php new file mode 100644 index 0000000..1e363bc --- /dev/null +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ClosedResource.php @@ -0,0 +1,32 @@ +genericType = $genericType; + } + public function underlyingType() : Type + { + return new String_(); + } + public function getGenericType() : ?Type + { + return $this->genericType; + } + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + */ + public function __toString() : string + { + if ($this->genericType === null) { + return 'enum-string'; + } + return 'enum-string<' . (string) $this->genericType . '>'; + } +} diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/False_.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/False_.php index efbd5e9..b21346a 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/False_.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/False_.php @@ -14,7 +14,6 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\PseudoType; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Boolean; -use function class_alias; /** * Value Object representing the PseudoType 'False', which is a Boolean type. * @@ -31,4 +30,3 @@ public function __toString() : string return 'false'; } } -class_alias(False_::class, 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\False_', \false); diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/FloatValue.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/FloatValue.php index 4fea1eb..840059b 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/FloatValue.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/FloatValue.php @@ -16,7 +16,7 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Float_; /** @psalm-immutable */ -class FloatValue implements PseudoType +class FloatValue extends Float_ implements PseudoType { /** @var float */ private $value; diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/Generic.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/Generic.php new file mode 100644 index 0000000..f725477 --- /dev/null +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/Generic.php @@ -0,0 +1,47 @@ +types = $types; + } + /** + * @return Type[] + */ + public function getTypes() : array + { + return $this->types; + } + public function __toString() : string + { + $objectType = (string) ($this->fqsen ?? 'object'); + return $objectType . '<' . implode(', ', $this->types) . '>'; + } +} diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/HtmlEscapedString.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/HtmlEscapedString.php index 41a3179..237c664 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/HtmlEscapedString.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/HtmlEscapedString.php @@ -15,7 +15,7 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\String_; /** - * Value Object representing the type 'string'. + * Value Object representing the type 'html-escaped-string'. * * @psalm-immutable */ diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/IntegerValue.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/IntegerValue.php index 7674de9..ae8c1b3 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/IntegerValue.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/IntegerValue.php @@ -16,7 +16,7 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Integer; /** @psalm-immutable */ -final class IntegerValue implements PseudoType +final class IntegerValue extends Integer implements PseudoType { /** @var int */ private $value; diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/InterfaceString.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/InterfaceString.php new file mode 100644 index 0000000..0f4c116 --- /dev/null +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/InterfaceString.php @@ -0,0 +1,48 @@ +genericType = $genericType; + } + public function underlyingType() : Type + { + return new String_(); + } + public function getGenericType() : ?Type + { + return $this->genericType; + } + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + */ + public function __toString() : string + { + if ($this->genericType === null) { + return 'interface-string'; + } + return 'interface-string<' . (string) $this->genericType . '>'; + } +} diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/KeyOf.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/KeyOf.php index 3e6d293..ef8576c 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/KeyOf.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/KeyOf.php @@ -14,7 +14,6 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\PseudoType; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\ArrayKey; /** * Value Object representing the `key-of` type. * diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/List_.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/List_.php index 716471f..7ca6a0f 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/List_.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/List_.php @@ -15,7 +15,6 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Array_; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Integer; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Mixed_; /** * Value Object representing the type 'list'. * @@ -36,7 +35,7 @@ public function __construct(?Type $valueType = null) */ public function __toString() : string { - if ($this->valueType instanceof Mixed_) { + if ($this->valueType === null) { return 'list'; } return 'list<' . $this->valueType . '>'; diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/LiteralString.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/LiteralString.php index 28d184e..ef9cb53 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/LiteralString.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/LiteralString.php @@ -15,7 +15,7 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\String_; /** - * Value Object representing the type 'string'. + * Value Object representing the type 'literal-string'. * * @psalm-immutable */ diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/LowercaseString.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/LowercaseString.php index b9568dc..a128d10 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/LowercaseString.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/LowercaseString.php @@ -15,7 +15,7 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\String_; /** - * Value Object representing the type 'string'. + * Value Object representing the type 'lowercase-string'. * * @psalm-immutable */ diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NegativeInteger.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NegativeInteger.php index ff45ceb..279d367 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NegativeInteger.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NegativeInteger.php @@ -15,7 +15,7 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Integer; /** - * Value Object representing the type 'int'. + * Value Object representing the type 'negative-int'. * * @psalm-immutable */ diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NeverReturn.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NeverReturn.php new file mode 100644 index 0000000..2386cf2 --- /dev/null +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NeverReturn.php @@ -0,0 +1,32 @@ +keyType) { - return 'non-empty-array<' . $this->keyType . ',' . $this->valueType . '>'; - } - if ($this->valueType instanceof Mixed_) { + if ($this->valueType === null) { return 'non-empty-array'; } + if ($this->keyType) { + return 'non-empty-array<' . $this->keyType . ', ' . $this->valueType . '>'; + } return 'non-empty-array<' . $this->valueType . '>'; } } diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyList.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyList.php index e3850c7..737b7a8 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyList.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyList.php @@ -15,7 +15,6 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Array_; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Integer; -use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Mixed_; /** * Value Object representing the type 'non-empty-list'. * @@ -36,7 +35,7 @@ public function __construct(?Type $valueType = null) */ public function __toString() : string { - if ($this->valueType instanceof Mixed_) { + if ($this->valueType === null) { return 'non-empty-list'; } return 'non-empty-list<' . $this->valueType . '>'; diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyLowercaseString.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyLowercaseString.php index a3fc12c..8df4738 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyLowercaseString.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyLowercaseString.php @@ -15,7 +15,7 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\String_; /** - * Value Object representing the type 'string'. + * Value Object representing the type 'non-empty-lowercase-string'. * * @psalm-immutable */ diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyString.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyString.php index a3e0a1c..a605d45 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyString.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyString.php @@ -15,7 +15,7 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\String_; /** - * Value Object representing the type 'string'. + * Value Object representing the type 'non-empty-string'. * * @psalm-immutable */ diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonFalsyString.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonFalsyString.php new file mode 100644 index 0000000..e8b35fc --- /dev/null +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/NonFalsyString.php @@ -0,0 +1,32 @@ +type . '>'; + } +} diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/PropertiesOf.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/PropertiesOf.php new file mode 100644 index 0000000..c7753c7 --- /dev/null +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/PropertiesOf.php @@ -0,0 +1,46 @@ +type = $type; + } + public function getType() : Type + { + return $this->type; + } + public function underlyingType() : Type + { + return new Array_(new Mixed_(), new String_()); + } + public function __toString() : string + { + return 'properties-of<' . $this->type . '>'; + } +} diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ProtectedPropertiesOf.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ProtectedPropertiesOf.php new file mode 100644 index 0000000..7efeb94 --- /dev/null +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/ProtectedPropertiesOf.php @@ -0,0 +1,26 @@ +type . '>'; + } +} diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/PublicPropertiesOf.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/PublicPropertiesOf.php new file mode 100644 index 0000000..195ba6a --- /dev/null +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/PublicPropertiesOf.php @@ -0,0 +1,26 @@ +type . '>'; + } +} diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/Scalar.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/Scalar.php new file mode 100644 index 0000000..b25345b --- /dev/null +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/Scalar.php @@ -0,0 +1,39 @@ +genericType = $genericType; + } public function underlyingType() : Type { return new String_(); } + public function getGenericType() : ?Type + { + return $this->genericType; + } /** * Returns a rendered output of the Type as it would be used in a DocBlock. */ public function __toString() : string { - return 'trait-string'; + if ($this->genericType === null) { + return 'trait-string'; + } + return 'trait-string<' . (string) $this->genericType . '>'; } } diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/True_.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/True_.php index 8eeda48..d112f94 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/True_.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/True_.php @@ -14,7 +14,6 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\PseudoType; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types\Boolean; -use function class_alias; /** * Value Object representing the PseudoType 'False', which is a Boolean type. * @@ -31,4 +30,3 @@ public function __toString() : string return 'true'; } } -class_alias(True_::class, 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\True_', \false); diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/TruthyString.php b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/TruthyString.php new file mode 100644 index 0000000..a6442e2 --- /dev/null +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/PseudoTypes/TruthyString.php @@ -0,0 +1,32 @@ + List of recognized keywords and unto which Value Object they map * @psalm-var array> */ - private $keywords = ['string' => String_::class, 'class-string' => ClassString::class, 'interface-string' => InterfaceString::class, 'html-escaped-string' => HtmlEscapedString::class, 'lowercase-string' => LowercaseString::class, 'non-empty-lowercase-string' => NonEmptyLowercaseString::class, 'non-empty-string' => NonEmptyString::class, 'numeric-string' => NumericString::class, 'numeric' => Numeric_::class, 'trait-string' => TraitString::class, 'int' => Integer::class, 'integer' => Integer::class, 'positive-int' => PositiveInteger::class, 'negative-int' => NegativeInteger::class, 'bool' => Boolean::class, 'boolean' => Boolean::class, 'real' => Float_::class, 'float' => Float_::class, 'double' => Float_::class, 'object' => Object_::class, 'mixed' => Mixed_::class, 'array' => Array_::class, 'array-key' => ArrayKey::class, 'non-empty-array' => NonEmptyArray::class, 'resource' => Resource_::class, 'void' => Void_::class, 'null' => Null_::class, 'scalar' => Scalar::class, 'callback' => Callable_::class, 'callable' => Callable_::class, 'callable-string' => CallableString::class, 'false' => False_::class, 'true' => True_::class, 'literal-string' => LiteralString::class, 'self' => Self_::class, '$this' => This::class, 'static' => Static_::class, 'parent' => Parent_::class, 'iterable' => Iterable_::class, 'never' => Never_::class, 'list' => List_::class, 'non-empty-list' => NonEmptyList::class]; + private $keywords = ['string' => String_::class, 'class-string' => ClassString::class, 'interface-string' => InterfaceString::class, 'html-escaped-string' => HtmlEscapedString::class, 'lowercase-string' => LowercaseString::class, 'non-empty-lowercase-string' => NonEmptyLowercaseString::class, 'non-empty-string' => NonEmptyString::class, 'numeric-string' => NumericString::class, 'numeric' => Numeric_::class, 'trait-string' => TraitString::class, 'enum-string' => EnumString::class, 'int' => Integer::class, 'integer' => Integer::class, 'positive-int' => PositiveInteger::class, 'negative-int' => NegativeInteger::class, 'bool' => Boolean::class, 'boolean' => Boolean::class, 'real' => Float_::class, 'float' => Float_::class, 'double' => Float_::class, 'object' => Object_::class, 'mixed' => Mixed_::class, 'array' => Array_::class, 'callable-array' => CallableArray::class, 'array-key' => ArrayKey::class, 'non-empty-array' => NonEmptyArray::class, 'resource' => Resource_::class, 'open-resource' => OpenResource::class, 'closed-resource' => ClosedResource::class, 'void' => Void_::class, 'null' => Null_::class, 'scalar' => Scalar::class, 'callback' => Callable_::class, 'callable' => Callable_::class, 'callable-string' => CallableString::class, 'false' => False_::class, 'true' => True_::class, 'literal-string' => LiteralString::class, 'self' => Self_::class, '$this' => This::class, 'static' => Static_::class, 'parent' => Parent_::class, 'iterable' => Iterable_::class, 'never' => Never_::class, 'never-return' => NeverReturn::class, 'never-returns' => NeverReturns::class, 'no-return' => NoReturn::class, 'list' => List_::class, 'non-empty-list' => NonEmptyList::class, 'non-falsy-string' => NonFalsyString::class, 'truthy-string' => TruthyString::class, 'non-positive-int' => NonPositiveInteger::class, 'non-negative-int' => NonNegativeInteger::class, 'non-zero-int' => NonZeroInteger::class]; /** * @psalm-readonly * @var FqsenResolver @@ -148,13 +163,8 @@ final class TypeResolver public function __construct(?FqsenResolver $fqsenResolver = null) { $this->fqsenResolver = $fqsenResolver ?: new FqsenResolver(); - if (class_exists(ParserConfig::class)) { - $this->typeParser = new TypeParser(new ParserConfig([]), new ConstExprParser(new ParserConfig([]))); - $this->lexer = new Lexer(new ParserConfig([])); - } else { - $this->typeParser = new TypeParser(new ConstExprParser()); - $this->lexer = new Lexer(); - } + $this->typeParser = new TypeParser(new ParserConfig([]), new ConstExprParser(new ParserConfig([]))); + $this->lexer = new Lexer(new ParserConfig([])); } /** * Analyzes the given type and returns the FQCN variant. @@ -185,7 +195,11 @@ public function resolve(string $type, ?Context $context = null) : Type $tokenIterator = new TokenIterator($tokens); $ast = $this->parse($tokenIterator); $type = $this->createType($ast, $context); - return $this->tryParseRemainingCompoundTypes($tokenIterator, $context, $type); + if ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_UNION) || $tokenIterator->isCurrentTokenType(Lexer::TOKEN_INTERSECTION)) { + Deprecation::trigger('phpdocumentor/type-resolver', 'https://github.com/phpDocumentor/TypeResolver/issues/184', 'Legacy nullable type detected, please update your code as + you are using nullable types in a docblock. support is removed in v2.0.0'); + } + return $type; } public function createType(?TypeNode $type, Context $context) : Type { @@ -221,24 +235,24 @@ public function createType(?TypeNode $type, Context $context) : Type case IdentifierTypeNode::class: return $this->resolveSingleType($type->name, $context); case IntersectionTypeNode::class: - return new Intersection(array_filter(array_map(function (TypeNode $nestedType) use($context) : Type { + return new Intersection(array_map(function (TypeNode $nestedType) use($context) : Type { $type = $this->createType($nestedType, $context); if ($type instanceof AggregatedType) { return new Expression($type); } return $type; - }, $type->types))); + }, $type->types)); case NullableTypeNode::class: $nestedType = $this->createType($type->type, $context); return new Nullable($nestedType); case UnionTypeNode::class: - return new Compound(array_filter(array_map(function (TypeNode $nestedType) use($context) : Type { + return new Compound(array_map(function (TypeNode $nestedType) use($context) : Type { $type = $this->createType($nestedType, $context); if ($type instanceof AggregatedType) { return new Expression($type); } return $type; - }, $type->types))); + }, $type->types)); case ThisTypeNode::class: return new This(); case ConditionalTypeNode::class: @@ -255,19 +269,19 @@ private function createFromGeneric(GenericTypeNode $type, Context $context) : Ty { switch (strtolower($type->type->name)) { case 'array': - return $this->createArray($type->genericTypes, $context); + $genericTypes = array_reverse($this->createTypesByTypeNodes($type->genericTypes, $context)); + return new Array_(...$genericTypes); + case 'non-empty-array': + $genericTypes = array_reverse($this->createTypesByTypeNodes($type->genericTypes, $context)); + return new NonEmptyArray(...$genericTypes); case 'class-string': - $subType = $this->createType($type->genericTypes[0], $context); - if (!$subType instanceof Object_ || $subType->getFqsen() === null) { - throw new RuntimeException($subType . ' is not a class string'); - } - return new ClassString($subType->getFqsen()); + return new ClassString($this->createType($type->genericTypes[0], $context)); case 'interface-string': - $subType = $this->createType($type->genericTypes[0], $context); - if (!$subType instanceof Object_ || $subType->getFqsen() === null) { - throw new RuntimeException($subType . ' is not a class string'); - } - return new InterfaceString($subType->getFqsen()); + return new InterfaceString($this->createType($type->genericTypes[0], $context)); + case 'trait-string': + return new TraitString($this->createType($type->genericTypes[0], $context)); + case 'enum-string': + return new EnumString($this->createType($type->genericTypes[0], $context)); case 'list': return new List_($this->createType($type->genericTypes[0], $context)); case 'non-empty-list': @@ -283,6 +297,14 @@ private function createFromGeneric(GenericTypeNode $type, Context $context) : Ty return new KeyOf($this->createType($type->genericTypes[0], $context)); case 'value-of': return new ValueOf($this->createType($type->genericTypes[0], $context)); + case 'properties-of': + return new PropertiesOf($this->createType($type->genericTypes[0], $context)); + case 'public-properties-of': + return new PublicPropertiesOf($this->createType($type->genericTypes[0], $context)); + case 'protected-properties-of': + return new ProtectedPropertiesOf($this->createType($type->genericTypes[0], $context)); + case 'private-properties-of': + return new PrivatePropertiesOf($this->createType($type->genericTypes[0], $context)); case 'int-mask': return new IntMask(...$this->createTypesByTypeNodes($type->genericTypes, $context)); case 'int-mask-of': @@ -292,16 +314,17 @@ private function createFromGeneric(GenericTypeNode $type, Context $context) : Ty case 'self': return new Self_(...$this->createTypesByTypeNodes($type->genericTypes, $context)); default: - $collectionType = $this->createType($type->type, $context); - if ($collectionType instanceof Object_ === \false) { - throw new RuntimeException(sprintf('%s is not a collection', (string) $collectionType)); + $mainType = $this->createType($type->type, $context); + if ($mainType instanceof Object_ === \false) { + throw new RuntimeException(sprintf('%s is an unsupported generic', (string) $mainType)); } - return new Collection($collectionType->getFqsen(), ...array_reverse($this->createTypesByTypeNodes($type->genericTypes, $context))); + $types = $this->createTypesByTypeNodes($type->genericTypes, $context); + return new Generic($mainType->getFqsen(), $types); } } private function createFromCallable(CallableTypeNode $type, Context $context) : Callable_ { - return new Callable_(array_map(function (CallableTypeParameterNode $param) use($context) : CallableParameter { + return new Callable_((string) $type->identifier, array_map(function (CallableTypeParameterNode $param) use($context) : CallableParameter { return new CallableParameter($this->createType($param->type, $context), $param->parameterName !== '' ? trim($param->parameterName, '$') : null, $param->isReference, $param->isVariadic, $param->isOptional); }, $type->parameters), $this->createType($type->returnType, $context)); } @@ -414,27 +437,6 @@ private function resolveTypedObject(string $type, ?Context $context = null) : Ob { return new Object_($this->fqsenResolver->resolve($type, $context)); } - /** @param TypeNode[] $typeNodes */ - private function createArray(array $typeNodes, Context $context) : Array_ - { - $types = array_reverse($this->createTypesByTypeNodes($typeNodes, $context)); - if (isset($types[1]) === \false) { - return new Array_(...$types); - } - if ($this->validArrayKeyType($types[1]) || $types[1] instanceof ArrayKey) { - return new Array_(...$types); - } - if ($types[1] instanceof Compound && $types[1]->getIterator()->count() === 2) { - if ($this->validArrayKeyType($types[1]->get(0)) && $this->validArrayKeyType($types[1]->get(1))) { - return new Array_(...$types); - } - } - throw new RuntimeException('An array can have only integers or strings as keys'); - } - private function validArrayKeyType(?Type $type) : bool - { - return $type instanceof String_ || $type instanceof Integer; - } private function parse(TokenIterator $tokenIterator) : TypeNode { try { @@ -444,36 +446,6 @@ private function parse(TokenIterator $tokenIterator) : TypeNode } return $ast; } - /** - * Will try to parse unsupported type notations by phpstan - * - * The phpstan parser doesn't support the illegal nullable combinations like this library does. - * This method will warn the user about those notations but for bc purposes we will still have it here. - */ - private function tryParseRemainingCompoundTypes(TokenIterator $tokenIterator, Context $context, Type $type) : Type - { - if ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_UNION) || $tokenIterator->isCurrentTokenType(Lexer::TOKEN_INTERSECTION)) { - Deprecation::trigger('phpdocumentor/type-resolver', 'https://github.com/phpDocumentor/TypeResolver/issues/184', 'Legacy nullable type detected, please update your code as - you are using nullable types in a docblock. support will be removed in v2.0.0'); - } - $continue = \true; - while ($continue) { - $continue = \false; - while ($tokenIterator->tryConsumeTokenType(Lexer::TOKEN_UNION)) { - $ast = $this->parse($tokenIterator); - $type2 = $this->createType($ast, $context); - $type = new Compound([$type, $type2]); - $continue = \true; - } - while ($tokenIterator->tryConsumeTokenType(Lexer::TOKEN_INTERSECTION)) { - $ast = $this->typeParser->parse($tokenIterator); - $type2 = $this->createType($ast, $context); - $type = new Intersection([$type, $type2]); - $continue = \true; - } - } - return $type; - } /** * @param TypeNode[] $nodes * diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/AbstractList.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/AbstractList.php index 0f6b68c..61aa982 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/AbstractList.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/AbstractList.php @@ -13,26 +13,26 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; /** - * Represents a list of values. This is an abstract class for Array_ and Collection. + * Represents a list of values. This is an abstract class for Array_ and List_. * * @psalm-immutable */ abstract class AbstractList implements Type { - /** @var Type */ + /** @var Type|null */ protected $valueType; /** @var Type|null */ protected $keyType; /** @var Type */ protected $defaultKeyType; + /** @var Type */ + protected $defaultValueType; /** * Initializes this representation of an array with the given Type. */ public function __construct(?Type $valueType = null, ?Type $keyType = null) { - if ($valueType === null) { - $valueType = new Mixed_(); - } + $this->defaultValueType = new Mixed_(); $this->valueType = $valueType; $this->defaultKeyType = new Compound([new String_(), new Integer()]); $this->keyType = $keyType; @@ -41,6 +41,10 @@ public function getOriginalKeyType() : ?Type { return $this->keyType; } + public function getOriginalValueType() : ?Type + { + return $this->valueType; + } /** * Returns the type for the keys of this array. */ @@ -53,22 +57,6 @@ public function getKeyType() : Type */ public function getValueType() : Type { - return $this->valueType; - } - /** - * Returns a rendered output of the Type as it would be used in a DocBlock. - */ - public function __toString() : string - { - if ($this->keyType) { - return 'array<' . $this->keyType . ',' . $this->valueType . '>'; - } - if ($this->valueType instanceof Mixed_) { - return 'array'; - } - if ($this->valueType instanceof Compound) { - return '(' . $this->valueType . ')[]'; - } - return $this->valueType . '[]'; + return $this->valueType ?? $this->defaultValueType; } } diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Array_.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Array_.php index 5849f46..01c86a1 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Array_.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Array_.php @@ -11,6 +11,8 @@ */ namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types; +use function preg_match; +use function substr; /** * Represents an array type as described in the PSR-5, the PHPDoc Standard. * @@ -24,4 +26,18 @@ */ class Array_ extends AbstractList { + public function __toString() : string + { + if ($this->valueType === null) { + return 'array'; + } + $valueTypeString = (string) $this->valueType; + if ($this->keyType) { + return 'array<' . $this->keyType . ', ' . $valueTypeString . '>'; + } + if (!preg_match('/[^\\w\\\\]/', $valueTypeString) || substr($valueTypeString, -2, 2) === '[]') { + return $valueTypeString . '[]'; + } + return 'array<' . $valueTypeString . '>'; + } } diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/CallableParameter.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/CallableParameter.php index c7c6f7f..c30e76c 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/CallableParameter.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/CallableParameter.php @@ -12,6 +12,7 @@ namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; +use function trim; /** * Value Object representing a Callable parameters. * @@ -57,4 +58,12 @@ public function isOptional() : bool { return $this->isOptional; } + public function __toString() : string + { + $reference = $this->isReference ? '&' : ''; + $variadic = $this->isVariadic ? '...' : ''; + $optional = $this->isOptional ? '=' : ''; + $name = $this->name !== null ? '$' . $this->name : ''; + return trim($this->type . ' ' . $reference . $variadic . $name . $optional); + } } diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Callable_.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Callable_.php index 22c9ac0..7fbca00 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Callable_.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Callable_.php @@ -12,6 +12,7 @@ namespace Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Types; use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; +use function implode; /** * Value Object representing a Callable type. * @@ -19,6 +20,8 @@ */ final class Callable_ implements Type { + /** @var string */ + private $identifier; /** @var Type|null */ private $returnType; /** @var CallableParameter[] */ @@ -26,11 +29,16 @@ final class Callable_ implements Type /** * @param CallableParameter[] $parameters */ - public function __construct(array $parameters = [], ?Type $returnType = null) + public function __construct(string $identifier = 'callable', array $parameters = [], ?Type $returnType = null) { + $this->identifier = $identifier; $this->parameters = $parameters; $this->returnType = $returnType; } + public function getIdentifier() : string + { + return $this->identifier; + } /** @return CallableParameter[] */ public function getParameters() : array { @@ -45,6 +53,14 @@ public function getReturnType() : ?Type */ public function __toString() : string { - return 'callable'; + if (!$this->parameters && $this->returnType === null) { + return $this->identifier; + } + if ($this->returnType instanceof self) { + $returnType = '(' . (string) $this->returnType . ')'; + } else { + $returnType = (string) $this->returnType; + } + return $this->identifier . '(' . implode(', ', $this->parameters) . '): ' . $returnType; } } diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Collection.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Collection.php deleted file mode 100644 index b812107..0000000 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Collection.php +++ /dev/null @@ -1,59 +0,0 @@ -` - * 2. `ACollectionObject` - * - * - ACollectionObject can be 'array' or an object that can act as an array - * - aValueType and aKeyType can be any type expression - * - * @psalm-immutable - */ -final class Collection extends AbstractList -{ - /** @var Fqsen|null */ - private $fqsen; - /** - * Initializes this representation of an array with the given Type or Fqsen. - */ - public function __construct(?Fqsen $fqsen, Type $valueType, ?Type $keyType = null) - { - parent::__construct($valueType, $keyType); - $this->fqsen = $fqsen; - } - /** - * Returns the FQSEN associated with this object. - */ - public function getFqsen() : ?Fqsen - { - return $this->fqsen; - } - /** - * Returns a rendered output of the Type as it would be used in a DocBlock. - */ - public function __toString() : string - { - $objectType = (string) ($this->fqsen ?? 'object'); - if ($this->keyType === null) { - return $objectType . '<' . $this->valueType . '>'; - } - return $objectType . '<' . $this->keyType . ',' . $this->valueType . '>'; - } -} diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/InterfaceString.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/InterfaceString.php deleted file mode 100644 index d8ac56f..0000000 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/InterfaceString.php +++ /dev/null @@ -1,49 +0,0 @@ -fqsen = $fqsen; - } - /** - * Returns the FQSEN associated with this object. - */ - public function getFqsen() : ?Fqsen - { - return $this->fqsen; - } - /** - * Returns a rendered output of the Type as it would be used in a DocBlock. - */ - public function __toString() : string - { - if ($this->fqsen === null) { - return 'interface-string'; - } - return 'interface-string<' . (string) $this->fqsen . '>'; - } -} diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Intersection.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Intersection.php index 52a4038..aa32cb1 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Intersection.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Intersection.php @@ -13,7 +13,7 @@ use Matomo\Dependencies\McpServer\phpDocumentor\Reflection\Type; /** - * Value Object representing a Compound Type. + * Value Object representing a Intersection Type. * * A Intersection Type is not so much a special keyword or object reference but is a series of Types that are separated * using an AND operator (`&`). This combination of types signifies that whatever is associated with this Intersection diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Iterable_.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Iterable_.php index 9edb4b7..a8d606f 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Iterable_.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Iterable_.php @@ -23,12 +23,12 @@ final class Iterable_ extends AbstractList */ public function __toString() : string { - if ($this->keyType) { - return 'iterable<' . $this->keyType . ',' . $this->valueType . '>'; - } - if ($this->valueType instanceof Mixed_) { + if ($this->valueType === null) { return 'iterable'; } + if ($this->keyType) { + return 'iterable<' . $this->keyType . ', ' . $this->valueType . '>'; + } return 'iterable<' . $this->valueType . '>'; } } diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Never_.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Never_.php index 63a75d1..1418dfa 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Never_.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Never_.php @@ -20,7 +20,7 @@ * * @psalm-immutable */ -final class Never_ implements Type +class Never_ implements Type { /** * Returns a rendered output of the Type as it would be used in a DocBlock. diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Object_.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Object_.php index b9f1ce0..dda6f9f 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Object_.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Object_.php @@ -24,10 +24,10 @@ * * @psalm-immutable */ -final class Object_ implements Type +class Object_ implements Type { /** @var Fqsen|null */ - private $fqsen; + protected $fqsen; /** * Initializes this object with an optional FQSEN, if not provided this object is considered 'untyped'. * diff --git a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Resource_.php b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Resource_.php index c111c06..7af2289 100644 --- a/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Resource_.php +++ b/vendor/prefixed/phpdocumentor/type-resolver/src/Types/Resource_.php @@ -17,7 +17,7 @@ * * @psalm-immutable */ -final class Resource_ implements Type +class Resource_ implements Type { /** * Returns a rendered output of the Type as it would be used in a DocBlock. diff --git a/vendor/prefixed/psr/http-client/CHANGELOG.md b/vendor/prefixed/psr/http-client/CHANGELOG.md new file mode 100644 index 0000000..babba7c --- /dev/null +++ b/vendor/prefixed/psr/http-client/CHANGELOG.md @@ -0,0 +1,31 @@ +# Changelog + +All notable changes to this project will be documented in this file, in reverse chronological order by release. + +## 1.0.3 + +Add `source` link in composer.json. No code changes. + +## 1.0.2 + +Allow PSR-7 (psr/http-message) 2.0. No code changes. + +## 1.0.1 + +Allow installation with PHP 8. No code changes. + +## 1.0.0 + +First stable release. No changes since 0.3.0. + +## 0.3.0 + +Added Interface suffix on exceptions + +## 0.2.0 + +All exceptions are in `Psr\Http\Client` namespace + +## 0.1.0 + +First release diff --git a/vendor/prefixed/symfony/finder/LICENSE b/vendor/prefixed/psr/http-client/LICENSE similarity index 79% rename from vendor/prefixed/symfony/finder/LICENSE rename to vendor/prefixed/psr/http-client/LICENSE index 0138f8f..cd5e002 100644 --- a/vendor/prefixed/symfony/finder/LICENSE +++ b/vendor/prefixed/psr/http-client/LICENSE @@ -1,14 +1,14 @@ -Copyright (c) 2004-present Fabien Potencier +Copyright (c) 2017 PHP Framework Interoperability Group -Permission is hereby granted, free of charge, to any person obtaining a copy +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/vendor/prefixed/psr/http-client/README.md b/vendor/prefixed/psr/http-client/README.md new file mode 100644 index 0000000..84af5c5 --- /dev/null +++ b/vendor/prefixed/psr/http-client/README.md @@ -0,0 +1,12 @@ +HTTP Client +=========== + +This repository holds all the common code related to [PSR-18 (HTTP Client)][psr-url]. + +Note that this is not a HTTP Client implementation of its own. It is merely abstractions that describe the components of a HTTP Client. + +The installable [package][package-url] and [implementations][implementation-url] are listed on Packagist. + +[psr-url]: https://www.php-fig.org/psr/psr-18 +[package-url]: https://packagist.org/packages/psr/http-client +[implementation-url]: https://packagist.org/providers/psr/http-client-implementation diff --git a/vendor/prefixed/psr/http-client/composer.json b/vendor/prefixed/psr/http-client/composer.json new file mode 100644 index 0000000..da104cd --- /dev/null +++ b/vendor/prefixed/psr/http-client/composer.json @@ -0,0 +1,35 @@ +{ + "name": "psr\/http-client", + "description": "Common interface for HTTP clients", + "keywords": [ + "psr", + "psr-18", + "http", + "http-client" + ], + "homepage": "https:\/\/github.com\/php-fig\/http-client", + "license": "MIT", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https:\/\/www.php-fig.org\/" + } + ], + "support": { + "source": "https:\/\/github.com\/php-fig\/http-client" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr\/http-message": "^1.0 || ^2.0" + }, + "autoload": { + "psr-4": { + "Matomo\\Dependencies\\McpServer\\Psr\\Http\\Client\\": "src\/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} \ No newline at end of file diff --git a/vendor/prefixed/psr/http-client/src/ClientExceptionInterface.php b/vendor/prefixed/psr/http-client/src/ClientExceptionInterface.php new file mode 100644 index 0000000..9d88219 --- /dev/null +++ b/vendor/prefixed/psr/http-client/src/ClientExceptionInterface.php @@ -0,0 +1,10 @@ + - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder\Comparator; - -/** - * @author Fabien Potencier - */ -class Comparator -{ - private string $target; - private string $operator; - public function __construct(string $target, string $operator = '==') - { - if (!\in_array($operator, ['>', '<', '>=', '<=', '==', '!='])) { - throw new \InvalidArgumentException(\sprintf('Invalid operator "%s".', $operator)); - } - $this->target = $target; - $this->operator = $operator; - } - /** - * Gets the target value. - */ - public function getTarget() : string - { - return $this->target; - } - /** - * Gets the comparison operator. - */ - public function getOperator() : string - { - return $this->operator; - } - /** - * Tests against the target. - */ - public function test(mixed $test) : bool - { - return match ($this->operator) { - '>' => $test > $this->target, - '>=' => $test >= $this->target, - '<' => $test < $this->target, - '<=' => $test <= $this->target, - '!=' => $test != $this->target, - default => $test == $this->target, - }; - } -} diff --git a/vendor/prefixed/symfony/finder/Comparator/DateComparator.php b/vendor/prefixed/symfony/finder/Comparator/DateComparator.php deleted file mode 100644 index dc1fdde..0000000 --- a/vendor/prefixed/symfony/finder/Comparator/DateComparator.php +++ /dev/null @@ -1,45 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder\Comparator; - -/** - * DateCompare compiles date comparisons. - * - * @author Fabien Potencier - */ -class DateComparator extends Comparator -{ - /** - * @param string $test A comparison string - * - * @throws \InvalidArgumentException If the test is not understood - */ - public function __construct(string $test) - { - if (!preg_match('#^\\s*(==|!=|[<>]=?|after|since|before|until)?\\s*(.+?)\\s*$#i', $test, $matches)) { - throw new \InvalidArgumentException(\sprintf('Don\'t understand "%s" as a date test.', $test)); - } - try { - $date = new \DateTimeImmutable($matches[2]); - $target = $date->format('U'); - } catch (\Exception) { - throw new \InvalidArgumentException(\sprintf('"%s" is not a valid date.', $matches[2])); - } - $operator = $matches[1] ?: '=='; - if ('since' === $operator || 'after' === $operator) { - $operator = '>'; - } - if ('until' === $operator || 'before' === $operator) { - $operator = '<'; - } - parent::__construct($target, $operator); - } -} diff --git a/vendor/prefixed/symfony/finder/Comparator/NumberComparator.php b/vendor/prefixed/symfony/finder/Comparator/NumberComparator.php deleted file mode 100644 index 7c9961f..0000000 --- a/vendor/prefixed/symfony/finder/Comparator/NumberComparator.php +++ /dev/null @@ -1,75 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder\Comparator; - -/** - * NumberComparator compiles a simple comparison to an anonymous - * subroutine, which you can call with a value to be tested again. - * - * Now this would be very pointless, if NumberCompare didn't understand - * magnitudes. - * - * The target value may use magnitudes of kilobytes (k, ki), - * megabytes (m, mi), or gigabytes (g, gi). Those suffixed - * with an i use the appropriate 2**n version in accordance with the - * IEC standard: http://physics.nist.gov/cuu/Units/binary.html - * - * Based on the Perl Number::Compare module. - * - * @author Fabien Potencier PHP port - * @author Richard Clamp Perl version - * @copyright 2004-2005 Fabien Potencier - * @copyright 2002 Richard Clamp - * - * @see http://physics.nist.gov/cuu/Units/binary.html - */ -class NumberComparator extends Comparator -{ - /** - * @param string|null $test A comparison string or null - * - * @throws \InvalidArgumentException If the test is not understood - */ - public function __construct(?string $test) - { - if (null === $test || !preg_match('#^\\s*(==|!=|[<>]=?)?\\s*([0-9\\.]+)\\s*([kmg]i?)?\\s*$#i', $test, $matches)) { - throw new \InvalidArgumentException(\sprintf('Don\'t understand "%s" as a number test.', $test ?? 'null')); - } - $target = $matches[2]; - if (!is_numeric($target)) { - throw new \InvalidArgumentException(\sprintf('Invalid number "%s".', $target)); - } - if (isset($matches[3])) { - // magnitude - switch (strtolower($matches[3])) { - case 'k': - $target *= 1000; - break; - case 'ki': - $target *= 1024; - break; - case 'm': - $target *= 1000000; - break; - case 'mi': - $target *= 1024 * 1024; - break; - case 'g': - $target *= 1000000000; - break; - case 'gi': - $target *= 1024 * 1024 * 1024; - break; - } - } - parent::__construct($target, $matches[1] ?: '=='); - } -} diff --git a/vendor/prefixed/symfony/finder/Exception/AccessDeniedException.php b/vendor/prefixed/symfony/finder/Exception/AccessDeniedException.php deleted file mode 100644 index c52a8c7..0000000 --- a/vendor/prefixed/symfony/finder/Exception/AccessDeniedException.php +++ /dev/null @@ -1,18 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder\Exception; - -/** - * @author Jean-François Simon - */ -class AccessDeniedException extends \UnexpectedValueException -{ -} diff --git a/vendor/prefixed/symfony/finder/Exception/DirectoryNotFoundException.php b/vendor/prefixed/symfony/finder/Exception/DirectoryNotFoundException.php deleted file mode 100644 index bb28126..0000000 --- a/vendor/prefixed/symfony/finder/Exception/DirectoryNotFoundException.php +++ /dev/null @@ -1,18 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder\Exception; - -/** - * @author Andreas Erhard - */ -class DirectoryNotFoundException extends \InvalidArgumentException -{ -} diff --git a/vendor/prefixed/symfony/finder/Finder.php b/vendor/prefixed/symfony/finder/Finder.php deleted file mode 100644 index 14654b2..0000000 --- a/vendor/prefixed/symfony/finder/Finder.php +++ /dev/null @@ -1,749 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder; - -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\Comparator\DateComparator; -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\Comparator\NumberComparator; -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\Exception\DirectoryNotFoundException; -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator\CustomFilterIterator; -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator\DateRangeFilterIterator; -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator\DepthRangeFilterIterator; -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator; -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator\FilecontentFilterIterator; -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator\FilenameFilterIterator; -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator\LazyIterator; -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator\SizeRangeFilterIterator; -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator\SortableIterator; -/** - * Finder allows to build rules to find files and directories. - * - * It is a thin wrapper around several specialized iterator classes. - * - * All rules may be invoked several times. - * - * All methods return the current Finder object to allow chaining: - * - * $finder = Finder::create()->files()->name('*.php')->in(__DIR__); - * - * @author Fabien Potencier - * - * @implements \IteratorAggregate - */ -class Finder implements \IteratorAggregate, \Countable -{ - public const IGNORE_VCS_FILES = 1; - public const IGNORE_DOT_FILES = 2; - public const IGNORE_VCS_IGNORED_FILES = 4; - private int $mode = 0; - private array $names = []; - private array $notNames = []; - private array $exclude = []; - private array $filters = []; - private array $pruneFilters = []; - private array $depths = []; - private array $sizes = []; - private bool $followLinks = \false; - private bool $reverseSorting = \false; - private \Closure|int|false $sort = \false; - private int $ignore = 0; - /** @var list */ - private array $dirs = []; - private array $dates = []; - /** @var list> */ - private array $iterators = []; - private array $contains = []; - private array $notContains = []; - private array $paths = []; - private array $notPaths = []; - private bool $ignoreUnreadableDirs = \false; - private static array $vcsPatterns = ['.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg']; - public function __construct() - { - $this->ignore = static::IGNORE_VCS_FILES | static::IGNORE_DOT_FILES; - } - /** - * Creates a new Finder. - */ - public static function create() : static - { - return new static(); - } - /** - * Restricts the matching to directories only. - * - * @return $this - */ - public function directories() : static - { - $this->mode = Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES; - return $this; - } - /** - * Restricts the matching to files only. - * - * @return $this - */ - public function files() : static - { - $this->mode = Iterator\FileTypeFilterIterator::ONLY_FILES; - return $this; - } - /** - * Adds tests for the directory depth. - * - * Usage: - * - * $finder->depth('> 1') // the Finder will start matching at level 1. - * $finder->depth('< 3') // the Finder will descend at most 3 levels of directories below the starting point. - * $finder->depth(['>= 1', '< 3']) - * - * @param string|int|string[]|int[] $levels The depth level expression or an array of depth levels - * - * @return $this - * - * @see DepthRangeFilterIterator - * @see NumberComparator - */ - public function depth(string|int|array $levels) : static - { - foreach ((array) $levels as $level) { - $this->depths[] = new NumberComparator($level); - } - return $this; - } - /** - * Adds tests for file dates (last modified). - * - * The date must be something that strtotime() is able to parse: - * - * $finder->date('since yesterday'); - * $finder->date('until 2 days ago'); - * $finder->date('> now - 2 hours'); - * $finder->date('>= 2005-10-15'); - * $finder->date(['>= 2005-10-15', '<= 2006-05-27']); - * - * @param string|string[] $dates A date range string or an array of date ranges - * - * @return $this - * - * @see strtotime - * @see DateRangeFilterIterator - * @see DateComparator - */ - public function date(string|array $dates) : static - { - foreach ((array) $dates as $date) { - $this->dates[] = new DateComparator($date); - } - return $this; - } - /** - * Adds rules that files must match. - * - * You can use patterns (delimited with / sign), globs or simple strings. - * - * $finder->name('/\.php$/') - * $finder->name('*.php') // same as above, without dot files - * $finder->name('test.php') - * $finder->name(['test.py', 'test.php']) - * - * @param string|string[] $patterns A pattern (a regexp, a glob, or a string) or an array of patterns - * - * @return $this - * - * @see FilenameFilterIterator - */ - public function name(string|array $patterns) : static - { - $this->names = array_merge($this->names, (array) $patterns); - return $this; - } - /** - * Adds rules that files must not match. - * - * @param string|string[] $patterns A pattern (a regexp, a glob, or a string) or an array of patterns - * - * @return $this - * - * @see FilenameFilterIterator - */ - public function notName(string|array $patterns) : static - { - $this->notNames = array_merge($this->notNames, (array) $patterns); - return $this; - } - /** - * Adds tests that file contents must match. - * - * Strings or PCRE patterns can be used: - * - * $finder->contains('Lorem ipsum') - * $finder->contains('/Lorem ipsum/i') - * $finder->contains(['dolor', '/ipsum/i']) - * - * @param string|string[] $patterns A pattern (string or regexp) or an array of patterns - * - * @return $this - * - * @see FilecontentFilterIterator - */ - public function contains(string|array $patterns) : static - { - $this->contains = array_merge($this->contains, (array) $patterns); - return $this; - } - /** - * Adds tests that file contents must not match. - * - * Strings or PCRE patterns can be used: - * - * $finder->notContains('Lorem ipsum') - * $finder->notContains('/Lorem ipsum/i') - * $finder->notContains(['lorem', '/dolor/i']) - * - * @param string|string[] $patterns A pattern (string or regexp) or an array of patterns - * - * @return $this - * - * @see FilecontentFilterIterator - */ - public function notContains(string|array $patterns) : static - { - $this->notContains = array_merge($this->notContains, (array) $patterns); - return $this; - } - /** - * Adds rules that filenames must match. - * - * You can use patterns (delimited with / sign) or simple strings. - * - * $finder->path('some/special/dir') - * $finder->path('/some\/special\/dir/') // same as above - * $finder->path(['some dir', 'another/dir']) - * - * Use only / as dirname separator. - * - * @param string|string[] $patterns A pattern (a regexp or a string) or an array of patterns - * - * @return $this - * - * @see FilenameFilterIterator - */ - public function path(string|array $patterns) : static - { - $this->paths = array_merge($this->paths, (array) $patterns); - return $this; - } - /** - * Adds rules that filenames must not match. - * - * You can use patterns (delimited with / sign) or simple strings. - * - * $finder->notPath('some/special/dir') - * $finder->notPath('/some\/special\/dir/') // same as above - * $finder->notPath(['some/file.txt', 'another/file.log']) - * - * Use only / as dirname separator. - * - * @param string|string[] $patterns A pattern (a regexp or a string) or an array of patterns - * - * @return $this - * - * @see FilenameFilterIterator - */ - public function notPath(string|array $patterns) : static - { - $this->notPaths = array_merge($this->notPaths, (array) $patterns); - return $this; - } - /** - * Adds tests for file sizes. - * - * $finder->size('> 10K'); - * $finder->size('<= 1Ki'); - * $finder->size(4); - * $finder->size(['> 10K', '< 20K']) - * - * @param string|int|string[]|int[] $sizes A size range string or an integer or an array of size ranges - * - * @return $this - * - * @see SizeRangeFilterIterator - * @see NumberComparator - */ - public function size(string|int|array $sizes) : static - { - foreach ((array) $sizes as $size) { - $this->sizes[] = new NumberComparator($size); - } - return $this; - } - /** - * Excludes directories. - * - * Directories passed as argument must be relative to the ones defined with the `in()` method. For example: - * - * $finder->in(__DIR__)->exclude('ruby'); - * - * @param string|array $dirs A directory path or an array of directories - * - * @return $this - * - * @see ExcludeDirectoryFilterIterator - */ - public function exclude(string|array $dirs) : static - { - $this->exclude = array_merge($this->exclude, (array) $dirs); - return $this; - } - /** - * Excludes "hidden" directories and files (starting with a dot). - * - * This option is enabled by default. - * - * @return $this - * - * @see ExcludeDirectoryFilterIterator - */ - public function ignoreDotFiles(bool $ignoreDotFiles) : static - { - if ($ignoreDotFiles) { - $this->ignore |= static::IGNORE_DOT_FILES; - } else { - $this->ignore &= ~static::IGNORE_DOT_FILES; - } - return $this; - } - /** - * Forces the finder to ignore version control directories. - * - * This option is enabled by default. - * - * @return $this - * - * @see ExcludeDirectoryFilterIterator - */ - public function ignoreVCS(bool $ignoreVCS) : static - { - if ($ignoreVCS) { - $this->ignore |= static::IGNORE_VCS_FILES; - } else { - $this->ignore &= ~static::IGNORE_VCS_FILES; - } - return $this; - } - /** - * Forces Finder to obey .gitignore and ignore files based on rules listed there. - * - * This option is disabled by default. - * - * @return $this - */ - public function ignoreVCSIgnored(bool $ignoreVCSIgnored) : static - { - if ($ignoreVCSIgnored) { - $this->ignore |= static::IGNORE_VCS_IGNORED_FILES; - } else { - $this->ignore &= ~static::IGNORE_VCS_IGNORED_FILES; - } - return $this; - } - /** - * Adds VCS patterns. - * - * @see ignoreVCS() - * - * @param string|string[] $pattern VCS patterns to ignore - * - * @return void - */ - public static function addVCSPattern(string|array $pattern) - { - foreach ((array) $pattern as $p) { - self::$vcsPatterns[] = $p; - } - self::$vcsPatterns = array_unique(self::$vcsPatterns); - } - /** - * Sorts files and directories by an anonymous function. - * - * The anonymous function receives two \SplFileInfo instances to compare. - * - * This can be slow as all the matching files and directories must be retrieved for comparison. - * - * @return $this - * - * @see SortableIterator - */ - public function sort(\Closure $closure) : static - { - $this->sort = $closure; - return $this; - } - /** - * Sorts files and directories by extension. - * - * This can be slow as all the matching files and directories must be retrieved for comparison. - * - * @return $this - * - * @see SortableIterator - */ - public function sortByExtension() : static - { - $this->sort = SortableIterator::SORT_BY_EXTENSION; - return $this; - } - /** - * Sorts files and directories by name. - * - * This can be slow as all the matching files and directories must be retrieved for comparison. - * - * @return $this - * - * @see SortableIterator - */ - public function sortByName(bool $useNaturalSort = \false) : static - { - $this->sort = $useNaturalSort ? SortableIterator::SORT_BY_NAME_NATURAL : SortableIterator::SORT_BY_NAME; - return $this; - } - /** - * Sorts files and directories by name case insensitive. - * - * This can be slow as all the matching files and directories must be retrieved for comparison. - * - * @return $this - * - * @see SortableIterator - */ - public function sortByCaseInsensitiveName(bool $useNaturalSort = \false) : static - { - $this->sort = $useNaturalSort ? SortableIterator::SORT_BY_NAME_NATURAL_CASE_INSENSITIVE : SortableIterator::SORT_BY_NAME_CASE_INSENSITIVE; - return $this; - } - /** - * Sorts files and directories by size. - * - * This can be slow as all the matching files and directories must be retrieved for comparison. - * - * @return $this - * - * @see SortableIterator - */ - public function sortBySize() : static - { - $this->sort = SortableIterator::SORT_BY_SIZE; - return $this; - } - /** - * Sorts files and directories by type (directories before files), then by name. - * - * This can be slow as all the matching files and directories must be retrieved for comparison. - * - * @return $this - * - * @see SortableIterator - */ - public function sortByType() : static - { - $this->sort = SortableIterator::SORT_BY_TYPE; - return $this; - } - /** - * Sorts files and directories by the last accessed time. - * - * This is the time that the file was last accessed, read or written to. - * - * This can be slow as all the matching files and directories must be retrieved for comparison. - * - * @return $this - * - * @see SortableIterator - */ - public function sortByAccessedTime() : static - { - $this->sort = SortableIterator::SORT_BY_ACCESSED_TIME; - return $this; - } - /** - * Reverses the sorting. - * - * @return $this - */ - public function reverseSorting() : static - { - $this->reverseSorting = \true; - return $this; - } - /** - * Sorts files and directories by the last inode changed time. - * - * This is the time that the inode information was last modified (permissions, owner, group or other metadata). - * - * On Windows, since inode is not available, changed time is actually the file creation time. - * - * This can be slow as all the matching files and directories must be retrieved for comparison. - * - * @return $this - * - * @see SortableIterator - */ - public function sortByChangedTime() : static - { - $this->sort = SortableIterator::SORT_BY_CHANGED_TIME; - return $this; - } - /** - * Sorts files and directories by the last modified time. - * - * This is the last time the actual contents of the file were last modified. - * - * This can be slow as all the matching files and directories must be retrieved for comparison. - * - * @return $this - * - * @see SortableIterator - */ - public function sortByModifiedTime() : static - { - $this->sort = SortableIterator::SORT_BY_MODIFIED_TIME; - return $this; - } - /** - * Filters the iterator with an anonymous function. - * - * The anonymous function receives a \SplFileInfo and must return false - * to remove files. - * - * @param \Closure(SplFileInfo): bool $closure - * @param bool $prune Whether to skip traversing directories further - * - * @return $this - * - * @see CustomFilterIterator - */ - public function filter(\Closure $closure) : static - { - $prune = 1 < \func_num_args() ? func_get_arg(1) : \false; - $this->filters[] = $closure; - if ($prune) { - $this->pruneFilters[] = $closure; - } - return $this; - } - /** - * Forces the following of symlinks. - * - * @return $this - */ - public function followLinks() : static - { - $this->followLinks = \true; - return $this; - } - /** - * Tells finder to ignore unreadable directories. - * - * By default, scanning unreadable directories content throws an AccessDeniedException. - * - * @return $this - */ - public function ignoreUnreadableDirs(bool $ignore = \true) : static - { - $this->ignoreUnreadableDirs = $ignore; - return $this; - } - /** - * Searches files and directories which match defined rules. - * - * @param string|string[] $dirs A directory path or an array of directories - * - * @return $this - * - * @throws DirectoryNotFoundException if one of the directories does not exist - */ - public function in(string|array $dirs) : static - { - $resolvedDirs = []; - foreach ((array) $dirs as $dir) { - if (is_dir($dir)) { - $resolvedDirs[] = [$this->normalizeDir($dir)]; - } elseif ($glob = glob($dir, (\defined('GLOB_BRACE') ? \GLOB_BRACE : 0) | \GLOB_ONLYDIR | \GLOB_NOSORT)) { - sort($glob); - $resolvedDirs[] = array_map($this->normalizeDir(...), $glob); - } else { - throw new DirectoryNotFoundException(\sprintf('The "%s" directory does not exist.', $dir)); - } - } - $this->dirs = array_merge($this->dirs, ...$resolvedDirs); - return $this; - } - /** - * Returns an Iterator for the current Finder configuration. - * - * This method implements the IteratorAggregate interface. - * - * @return \Iterator - * - * @throws \LogicException if the in() method has not been called - */ - public function getIterator() : \Iterator - { - if (!$this->dirs && !$this->iterators) { - throw new \LogicException('You must call one of in() or append() methods before iterating over a Finder.'); - } - if (1 === \count($this->dirs) && !$this->iterators) { - $iterator = $this->searchInDirectory($this->dirs[0]); - } else { - $iterator = new \AppendIterator(); - foreach ($this->dirs as $dir) { - $iterator->append(new \IteratorIterator(new LazyIterator(fn() => $this->searchInDirectory($dir)))); - } - foreach ($this->iterators as $it) { - $iterator->append(new \IteratorIterator(new LazyIterator(static function () use($it) { - foreach ($it as $file) { - if (!$file instanceof \SplFileInfo) { - $file = new \SplFileInfo($file); - } - $key = $file->getPathname(); - if (!$file instanceof SplFileInfo) { - $file = new SplFileInfo($key, $file->getPath(), $key); - } - (yield $key => $file); - } - }))); - } - } - if ($this->sort || $this->reverseSorting) { - $iterator = (new SortableIterator($iterator, $this->sort, $this->reverseSorting))->getIterator(); - } - return $iterator; - } - /** - * Appends an existing set of files/directories to the finder. - * - * The set can be another Finder, an Iterator, an IteratorAggregate, or even a plain array. - * - * @param iterable $iterator - * - * @return $this - */ - public function append(iterable $iterator) : static - { - $this->iterators[] = $iterator; - return $this; - } - /** - * Check if any results were found. - */ - public function hasResults() : bool - { - foreach ($this->getIterator() as $_) { - return \true; - } - return \false; - } - /** - * Counts all the results collected by the iterators. - */ - public function count() : int - { - return iterator_count($this->getIterator()); - } - private function searchInDirectory(string $dir) : \Iterator - { - $exclude = $this->exclude; - $notPaths = $this->notPaths; - if ($this->pruneFilters) { - $exclude = array_merge($exclude, $this->pruneFilters); - } - if (static::IGNORE_VCS_FILES === (static::IGNORE_VCS_FILES & $this->ignore)) { - $exclude = array_merge($exclude, self::$vcsPatterns); - } - if (static::IGNORE_DOT_FILES === (static::IGNORE_DOT_FILES & $this->ignore)) { - $notPaths[] = '#(^|/)\\..+(/|$)#'; - } - $minDepth = 0; - $maxDepth = \PHP_INT_MAX; - foreach ($this->depths as $comparator) { - switch ($comparator->getOperator()) { - case '>': - $minDepth = $comparator->getTarget() + 1; - break; - case '>=': - $minDepth = $comparator->getTarget(); - break; - case '<': - $maxDepth = $comparator->getTarget() - 1; - break; - case '<=': - $maxDepth = $comparator->getTarget(); - break; - default: - $minDepth = $maxDepth = $comparator->getTarget(); - } - } - $flags = \RecursiveDirectoryIterator::SKIP_DOTS; - if ($this->followLinks) { - $flags |= \RecursiveDirectoryIterator::FOLLOW_SYMLINKS; - } - $iterator = new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs); - if ($exclude) { - $iterator = new ExcludeDirectoryFilterIterator($iterator, $exclude); - } - $iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::SELF_FIRST); - if ($minDepth > 0 || $maxDepth < \PHP_INT_MAX) { - $iterator = new DepthRangeFilterIterator($iterator, $minDepth, $maxDepth); - } - if ($this->mode) { - $iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode); - } - if ($this->names || $this->notNames) { - $iterator = new FilenameFilterIterator($iterator, $this->names, $this->notNames); - } - if ($this->contains || $this->notContains) { - $iterator = new FilecontentFilterIterator($iterator, $this->contains, $this->notContains); - } - if ($this->sizes) { - $iterator = new SizeRangeFilterIterator($iterator, $this->sizes); - } - if ($this->dates) { - $iterator = new DateRangeFilterIterator($iterator, $this->dates); - } - if ($this->filters) { - $iterator = new CustomFilterIterator($iterator, $this->filters); - } - if ($this->paths || $notPaths) { - $iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $notPaths); - } - if (static::IGNORE_VCS_IGNORED_FILES === (static::IGNORE_VCS_IGNORED_FILES & $this->ignore)) { - $iterator = new Iterator\VcsIgnoredFilterIterator($iterator, $dir); - } - return $iterator; - } - /** - * Normalizes given directory names by removing trailing slashes. - * - * Excluding: (s)ftp:// or ssh2.(s)ftp:// wrapper - */ - private function normalizeDir(string $dir) : string - { - if ('/' === $dir) { - return $dir; - } - $dir = rtrim($dir, '/' . \DIRECTORY_SEPARATOR); - if (preg_match('#^(ssh2\\.)?s?ftp://#', $dir)) { - $dir .= '/'; - } - return $dir; - } -} diff --git a/vendor/prefixed/symfony/finder/Gitignore.php b/vendor/prefixed/symfony/finder/Gitignore.php deleted file mode 100644 index d71af7b..0000000 --- a/vendor/prefixed/symfony/finder/Gitignore.php +++ /dev/null @@ -1,79 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder; - -/** - * Gitignore matches against text. - * - * @author Michael Voříšek - * @author Ahmed Abdou - */ -class Gitignore -{ - /** - * Returns a regexp which is the equivalent of the gitignore pattern. - * - * Format specification: https://git-scm.com/docs/gitignore#_pattern_format - */ - public static function toRegex(string $gitignoreFileContent) : string - { - return self::buildRegex($gitignoreFileContent, \false); - } - public static function toRegexMatchingNegatedPatterns(string $gitignoreFileContent) : string - { - return self::buildRegex($gitignoreFileContent, \true); - } - private static function buildRegex(string $gitignoreFileContent, bool $inverted) : string - { - $gitignoreFileContent = preg_replace('~(? '[' . ('' !== $matches[1] ? '^' : '') . str_replace('\\-', '-', $matches[2]) . ']', $regex); - $regex = preg_replace('~(?:(?:\\\\\\*){2,}(/?))+~', '(?:(?:(?!//).(? - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder; - -/** - * Glob matches globbing patterns against text. - * - * if match_glob("foo.*", "foo.bar") echo "matched\n"; - * - * // prints foo.bar and foo.baz - * $regex = glob_to_regex("foo.*"); - * for (['foo.bar', 'foo.baz', 'foo', 'bar'] as $t) - * { - * if (/$regex/) echo "matched: $car\n"; - * } - * - * Glob implements glob(3) style matching that can be used to match - * against text, rather than fetching names from a filesystem. - * - * Based on the Perl Text::Glob module. - * - * @author Fabien Potencier PHP port - * @author Richard Clamp Perl version - * @copyright 2004-2005 Fabien Potencier - * @copyright 2002 Richard Clamp - */ -class Glob -{ - /** - * Returns a regexp which is the equivalent of the glob pattern. - */ - public static function toRegex(string $glob, bool $strictLeadingDot = \true, bool $strictWildcardSlash = \true, string $delimiter = '#') : string - { - $firstByte = \true; - $escaping = \false; - $inCurlies = 0; - $regex = ''; - if ($unanchored = str_starts_with($glob, '**/')) { - $glob = '/' . $glob; - } - $sizeGlob = \strlen($glob); - for ($i = 0; $i < $sizeGlob; ++$i) { - $car = $glob[$i]; - if ($firstByte && $strictLeadingDot && '.' !== $car) { - $regex .= '(?=[^\\.])'; - } - $firstByte = '/' === $car; - if ($firstByte && $strictWildcardSlash && isset($glob[$i + 2]) && '**' === $glob[$i + 1] . $glob[$i + 2] && (!isset($glob[$i + 3]) || '/' === $glob[$i + 3])) { - $car = '[^/]++/'; - if (!isset($glob[$i + 3])) { - $car .= '?'; - } - if ($strictLeadingDot) { - $car = '(?=[^\\.])' . $car; - } - $car = '/(?:' . $car . ')*'; - $i += 2 + isset($glob[$i + 3]); - if ('/' === $delimiter) { - $car = str_replace('/', '\\/', $car); - } - } - if ($delimiter === $car || '.' === $car || '(' === $car || ')' === $car || '|' === $car || '+' === $car || '^' === $car || '$' === $car) { - $regex .= "\\{$car}"; - } elseif ('*' === $car) { - $regex .= $escaping ? '\\*' : ($strictWildcardSlash ? '[^/]*' : '.*'); - } elseif ('?' === $car) { - $regex .= $escaping ? '\\?' : ($strictWildcardSlash ? '[^/]' : '.'); - } elseif ('{' === $car) { - $regex .= $escaping ? '\\{' : '('; - if (!$escaping) { - ++$inCurlies; - } - } elseif ('}' === $car && $inCurlies) { - $regex .= $escaping ? '}' : ')'; - if (!$escaping) { - --$inCurlies; - } - } elseif (',' === $car && $inCurlies) { - $regex .= $escaping ? ',' : '|'; - } elseif ('\\' === $car) { - if ($escaping) { - $regex .= '\\\\'; - $escaping = \false; - } else { - $escaping = \true; - } - continue; - } else { - $regex .= $car; - } - $escaping = \false; - } - if ($unanchored) { - $regex = substr_replace($regex, '?', 1 + ('/' === $delimiter) + ($strictLeadingDot ? \strlen('(?=[^\\.])') : 0), 0); - } - return $delimiter . '^' . $regex . '$' . $delimiter; - } -} diff --git a/vendor/prefixed/symfony/finder/Iterator/CustomFilterIterator.php b/vendor/prefixed/symfony/finder/Iterator/CustomFilterIterator.php deleted file mode 100644 index c8d162b..0000000 --- a/vendor/prefixed/symfony/finder/Iterator/CustomFilterIterator.php +++ /dev/null @@ -1,55 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator; - -/** - * CustomFilterIterator filters files by applying anonymous functions. - * - * The anonymous function receives a \SplFileInfo and must return false - * to remove files. - * - * @author Fabien Potencier - * - * @extends \FilterIterator - */ -class CustomFilterIterator extends \FilterIterator -{ - private array $filters = []; - /** - * @param \Iterator $iterator The Iterator to filter - * @param callable[] $filters An array of PHP callbacks - * - * @throws \InvalidArgumentException - */ - public function __construct(\Iterator $iterator, array $filters) - { - foreach ($filters as $filter) { - if (!\is_callable($filter)) { - throw new \InvalidArgumentException('Invalid PHP callback.'); - } - } - $this->filters = $filters; - parent::__construct($iterator); - } - /** - * Filters the iterator values. - */ - public function accept() : bool - { - $fileinfo = $this->current(); - foreach ($this->filters as $filter) { - if (\false === $filter($fileinfo)) { - return \false; - } - } - return \true; - } -} diff --git a/vendor/prefixed/symfony/finder/Iterator/DateRangeFilterIterator.php b/vendor/prefixed/symfony/finder/Iterator/DateRangeFilterIterator.php deleted file mode 100644 index 816c7d1..0000000 --- a/vendor/prefixed/symfony/finder/Iterator/DateRangeFilterIterator.php +++ /dev/null @@ -1,50 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator; - -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\Comparator\DateComparator; -/** - * DateRangeFilterIterator filters out files that are not in the given date range (last modified dates). - * - * @author Fabien Potencier - * - * @extends \FilterIterator - */ -class DateRangeFilterIterator extends \FilterIterator -{ - private array $comparators = []; - /** - * @param \Iterator $iterator - * @param DateComparator[] $comparators - */ - public function __construct(\Iterator $iterator, array $comparators) - { - $this->comparators = $comparators; - parent::__construct($iterator); - } - /** - * Filters the iterator values. - */ - public function accept() : bool - { - $fileinfo = $this->current(); - if (!file_exists($fileinfo->getPathname())) { - return \false; - } - $filedate = $fileinfo->getMTime(); - foreach ($this->comparators as $compare) { - if (!$compare->test($filedate)) { - return \false; - } - } - return \true; - } -} diff --git a/vendor/prefixed/symfony/finder/Iterator/DepthRangeFilterIterator.php b/vendor/prefixed/symfony/finder/Iterator/DepthRangeFilterIterator.php deleted file mode 100644 index 180c7e5..0000000 --- a/vendor/prefixed/symfony/finder/Iterator/DepthRangeFilterIterator.php +++ /dev/null @@ -1,44 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator; - -/** - * DepthRangeFilterIterator limits the directory depth. - * - * @author Fabien Potencier - * - * @template-covariant TKey - * @template-covariant TValue - * - * @extends \FilterIterator - */ -class DepthRangeFilterIterator extends \FilterIterator -{ - private int $minDepth = 0; - /** - * @param \RecursiveIteratorIterator<\RecursiveIterator> $iterator The Iterator to filter - * @param int $minDepth The min depth - * @param int $maxDepth The max depth - */ - public function __construct(\RecursiveIteratorIterator $iterator, int $minDepth = 0, int $maxDepth = \PHP_INT_MAX) - { - $this->minDepth = $minDepth; - $iterator->setMaxDepth(\PHP_INT_MAX === $maxDepth ? -1 : $maxDepth); - parent::__construct($iterator); - } - /** - * Filters the iterator values. - */ - public function accept() : bool - { - return $this->getInnerIterator()->getDepth() >= $this->minDepth; - } -} diff --git a/vendor/prefixed/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php b/vendor/prefixed/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php deleted file mode 100644 index 713cc0e..0000000 --- a/vendor/prefixed/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php +++ /dev/null @@ -1,95 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator; - -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\SplFileInfo; -/** - * ExcludeDirectoryFilterIterator filters out directories. - * - * @author Fabien Potencier - * - * @extends \FilterIterator - * - * @implements \RecursiveIterator - */ -class ExcludeDirectoryFilterIterator extends \FilterIterator implements \RecursiveIterator -{ - /** @var \Iterator */ - private \Iterator $iterator; - private bool $isRecursive; - /** @var array */ - private array $excludedDirs = []; - private ?string $excludedPattern = null; - /** @var list */ - private array $pruneFilters = []; - /** - * @param \Iterator $iterator The Iterator to filter - * @param list $directories An array of directories to exclude - */ - public function __construct(\Iterator $iterator, array $directories) - { - $this->iterator = $iterator; - $this->isRecursive = $iterator instanceof \RecursiveIterator; - $patterns = []; - foreach ($directories as $directory) { - if (!\is_string($directory)) { - if (!\is_callable($directory)) { - throw new \InvalidArgumentException('Invalid PHP callback.'); - } - $this->pruneFilters[] = $directory; - continue; - } - $directory = rtrim($directory, '/'); - if (!$this->isRecursive || str_contains($directory, '/')) { - $patterns[] = preg_quote($directory, '#'); - } else { - $this->excludedDirs[$directory] = \true; - } - } - if ($patterns) { - $this->excludedPattern = '#(?:^|/)(?:' . implode('|', $patterns) . ')(?:/|$)#'; - } - parent::__construct($iterator); - } - /** - * Filters the iterator values. - */ - public function accept() : bool - { - if ($this->isRecursive && isset($this->excludedDirs[$this->getFilename()]) && $this->isDir()) { - return \false; - } - if ($this->excludedPattern) { - $path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath(); - $path = str_replace('\\', '/', $path); - return !preg_match($this->excludedPattern, $path); - } - if ($this->pruneFilters && $this->hasChildren()) { - foreach ($this->pruneFilters as $pruneFilter) { - if (!$pruneFilter($this->current())) { - return \false; - } - } - } - return \true; - } - public function hasChildren() : bool - { - return $this->isRecursive && $this->iterator->hasChildren(); - } - public function getChildren() : self - { - $children = new self($this->iterator->getChildren(), []); - $children->excludedDirs = $this->excludedDirs; - $children->excludedPattern = $this->excludedPattern; - return $children; - } -} diff --git a/vendor/prefixed/symfony/finder/Iterator/FileTypeFilterIterator.php b/vendor/prefixed/symfony/finder/Iterator/FileTypeFilterIterator.php deleted file mode 100644 index 70199d3..0000000 --- a/vendor/prefixed/symfony/finder/Iterator/FileTypeFilterIterator.php +++ /dev/null @@ -1,47 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator; - -/** - * FileTypeFilterIterator only keeps files, directories, or both. - * - * @author Fabien Potencier - * - * @extends \FilterIterator - */ -class FileTypeFilterIterator extends \FilterIterator -{ - public const ONLY_FILES = 1; - public const ONLY_DIRECTORIES = 2; - private int $mode; - /** - * @param \Iterator $iterator The Iterator to filter - * @param int $mode The mode (self::ONLY_FILES or self::ONLY_DIRECTORIES) - */ - public function __construct(\Iterator $iterator, int $mode) - { - $this->mode = $mode; - parent::__construct($iterator); - } - /** - * Filters the iterator values. - */ - public function accept() : bool - { - $fileinfo = $this->current(); - if (self::ONLY_DIRECTORIES === (self::ONLY_DIRECTORIES & $this->mode) && $fileinfo->isFile()) { - return \false; - } elseif (self::ONLY_FILES === (self::ONLY_FILES & $this->mode) && $fileinfo->isDir()) { - return \false; - } - return \true; - } -} diff --git a/vendor/prefixed/symfony/finder/Iterator/FilecontentFilterIterator.php b/vendor/prefixed/symfony/finder/Iterator/FilecontentFilterIterator.php deleted file mode 100644 index 3877921..0000000 --- a/vendor/prefixed/symfony/finder/Iterator/FilecontentFilterIterator.php +++ /dev/null @@ -1,51 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator; - -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\SplFileInfo; -/** - * FilecontentFilterIterator filters files by their contents using patterns (regexps or strings). - * - * @author Fabien Potencier - * @author Włodzimierz Gajda - * - * @extends MultiplePcreFilterIterator - */ -class FilecontentFilterIterator extends MultiplePcreFilterIterator -{ - /** - * Filters the iterator values. - */ - public function accept() : bool - { - if (!$this->matchRegexps && !$this->noMatchRegexps) { - return \true; - } - $fileinfo = $this->current(); - if ($fileinfo->isDir() || !$fileinfo->isReadable()) { - return \false; - } - $content = $fileinfo->getContents(); - if (!$content) { - return \false; - } - return $this->isAccepted($content); - } - /** - * Converts string to regexp if necessary. - * - * @param string $str Pattern: string or regexp - */ - protected function toRegex(string $str) : string - { - return $this->isRegex($str) ? $str : '/' . preg_quote($str, '/') . '/'; - } -} diff --git a/vendor/prefixed/symfony/finder/Iterator/FilenameFilterIterator.php b/vendor/prefixed/symfony/finder/Iterator/FilenameFilterIterator.php deleted file mode 100644 index b8d56df..0000000 --- a/vendor/prefixed/symfony/finder/Iterator/FilenameFilterIterator.php +++ /dev/null @@ -1,42 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator; - -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\Glob; -/** - * FilenameFilterIterator filters files by patterns (a regexp, a glob, or a string). - * - * @author Fabien Potencier - * - * @extends MultiplePcreFilterIterator - */ -class FilenameFilterIterator extends MultiplePcreFilterIterator -{ - /** - * Filters the iterator values. - */ - public function accept() : bool - { - return $this->isAccepted($this->current()->getFilename()); - } - /** - * Converts glob to regexp. - * - * PCRE patterns are left unchanged. - * Glob strings are transformed with Glob::toRegex(). - * - * @param string $str Pattern: glob or regexp - */ - protected function toRegex(string $str) : string - { - return $this->isRegex($str) ? $str : Glob::toRegex($str); - } -} diff --git a/vendor/prefixed/symfony/finder/Iterator/LazyIterator.php b/vendor/prefixed/symfony/finder/Iterator/LazyIterator.php deleted file mode 100644 index 3d59bbb..0000000 --- a/vendor/prefixed/symfony/finder/Iterator/LazyIterator.php +++ /dev/null @@ -1,29 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator; - -/** - * @author Jérémy Derussé - * - * @internal - */ -class LazyIterator implements \IteratorAggregate -{ - private \Closure $iteratorFactory; - public function __construct(callable $iteratorFactory) - { - $this->iteratorFactory = $iteratorFactory(...); - } - public function getIterator() : \Traversable - { - yield from ($this->iteratorFactory)(); - } -} diff --git a/vendor/prefixed/symfony/finder/Iterator/MultiplePcreFilterIterator.php b/vendor/prefixed/symfony/finder/Iterator/MultiplePcreFilterIterator.php deleted file mode 100644 index 745ad09..0000000 --- a/vendor/prefixed/symfony/finder/Iterator/MultiplePcreFilterIterator.php +++ /dev/null @@ -1,96 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator; - -/** - * MultiplePcreFilterIterator filters files using patterns (regexps, globs or strings). - * - * @author Fabien Potencier - * - * @template-covariant TKey - * @template-covariant TValue - * - * @extends \FilterIterator - */ -abstract class MultiplePcreFilterIterator extends \FilterIterator -{ - protected $matchRegexps = []; - protected $noMatchRegexps = []; - /** - * @param \Iterator $iterator The Iterator to filter - * @param string[] $matchPatterns An array of patterns that need to match - * @param string[] $noMatchPatterns An array of patterns that need to not match - */ - public function __construct(\Iterator $iterator, array $matchPatterns, array $noMatchPatterns) - { - foreach ($matchPatterns as $pattern) { - $this->matchRegexps[] = $this->toRegex($pattern); - } - foreach ($noMatchPatterns as $pattern) { - $this->noMatchRegexps[] = $this->toRegex($pattern); - } - parent::__construct($iterator); - } - /** - * Checks whether the string is accepted by the regex filters. - * - * If there is no regexps defined in the class, this method will accept the string. - * Such case can be handled by child classes before calling the method if they want to - * apply a different behavior. - */ - protected function isAccepted(string $string) : bool - { - // should at least not match one rule to exclude - foreach ($this->noMatchRegexps as $regex) { - if (preg_match($regex, $string)) { - return \false; - } - } - // should at least match one rule - if ($this->matchRegexps) { - foreach ($this->matchRegexps as $regex) { - if (preg_match($regex, $string)) { - return \true; - } - } - return \false; - } - // If there is no match rules, the file is accepted - return \true; - } - /** - * Checks whether the string is a regex. - */ - protected function isRegex(string $str) : bool - { - $availableModifiers = 'imsxuADU'; - if (\PHP_VERSION_ID >= 80200) { - $availableModifiers .= 'n'; - } - if (preg_match('/^(.{3,}?)[' . $availableModifiers . ']*$/', $str, $m)) { - $start = substr($m[1], 0, 1); - $end = substr($m[1], -1); - if ($start === $end) { - return !preg_match('/[*?[:alnum:] \\\\]/', $start); - } - foreach ([['{', '}'], ['(', ')'], ['[', ']'], ['<', '>']] as $delimiters) { - if ($start === $delimiters[0] && $end === $delimiters[1]) { - return \true; - } - } - } - return \false; - } - /** - * Converts string into regexp. - */ - protected abstract function toRegex(string $str) : string; -} diff --git a/vendor/prefixed/symfony/finder/Iterator/PathFilterIterator.php b/vendor/prefixed/symfony/finder/Iterator/PathFilterIterator.php deleted file mode 100644 index ad6562e..0000000 --- a/vendor/prefixed/symfony/finder/Iterator/PathFilterIterator.php +++ /dev/null @@ -1,51 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator; - -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\SplFileInfo; -/** - * PathFilterIterator filters files by path patterns (e.g. some/special/dir). - * - * @author Fabien Potencier - * @author Włodzimierz Gajda - * - * @extends MultiplePcreFilterIterator - */ -class PathFilterIterator extends MultiplePcreFilterIterator -{ - /** - * Filters the iterator values. - */ - public function accept() : bool - { - $filename = $this->current()->getRelativePathname(); - if ('\\' === \DIRECTORY_SEPARATOR) { - $filename = str_replace('\\', '/', $filename); - } - return $this->isAccepted($filename); - } - /** - * Converts strings to regexp. - * - * PCRE patterns are left unchanged. - * - * Default conversion: - * 'lorem/ipsum/dolor' ==> 'lorem\/ipsum\/dolor/' - * - * Use only / as directory separator (on Windows also). - * - * @param string $str Pattern: regexp or dirname - */ - protected function toRegex(string $str) : string - { - return $this->isRegex($str) ? $str : '/' . preg_quote($str, '/') . '/'; - } -} diff --git a/vendor/prefixed/symfony/finder/Iterator/RecursiveDirectoryIterator.php b/vendor/prefixed/symfony/finder/Iterator/RecursiveDirectoryIterator.php deleted file mode 100644 index 2853744..0000000 --- a/vendor/prefixed/symfony/finder/Iterator/RecursiveDirectoryIterator.php +++ /dev/null @@ -1,112 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator; - -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\Exception\AccessDeniedException; -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\SplFileInfo; -/** - * Extends the \RecursiveDirectoryIterator to support relative paths. - * - * @author Victor Berchet - * - * @extends \RecursiveDirectoryIterator - */ -class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator -{ - private bool $ignoreUnreadableDirs; - private bool $ignoreFirstRewind = \true; - // these 3 properties take part of the performance optimization to avoid redoing the same work in all iterations - private string $rootPath; - private string $subPath; - private string $directorySeparator = '/'; - /** - * @throws \RuntimeException - */ - public function __construct(string $path, int $flags, bool $ignoreUnreadableDirs = \false) - { - if ($flags & (self::CURRENT_AS_PATHNAME | self::CURRENT_AS_SELF)) { - throw new \RuntimeException('This iterator only support returning current as fileinfo.'); - } - parent::__construct($path, $flags); - $this->ignoreUnreadableDirs = $ignoreUnreadableDirs; - $this->rootPath = $path; - if ('/' !== \DIRECTORY_SEPARATOR && !($flags & self::UNIX_PATHS)) { - $this->directorySeparator = \DIRECTORY_SEPARATOR; - } - } - /** - * Return an instance of SplFileInfo with support for relative paths. - */ - public function current() : SplFileInfo - { - // the logic here avoids redoing the same work in all iterations - if (!isset($this->subPath)) { - $this->subPath = $this->getSubPath(); - } - $subPathname = $this->subPath; - if ('' !== $subPathname) { - $subPathname .= $this->directorySeparator; - } - $subPathname .= $this->getFilename(); - $basePath = $this->rootPath; - if ('/' !== $basePath && !str_ends_with($basePath, $this->directorySeparator) && !str_ends_with($basePath, '/')) { - $basePath .= $this->directorySeparator; - } - return new SplFileInfo($basePath . $subPathname, $this->subPath, $subPathname); - } - public function hasChildren(bool $allowLinks = \false) : bool - { - $hasChildren = parent::hasChildren($allowLinks); - if (!$hasChildren || !$this->ignoreUnreadableDirs) { - return $hasChildren; - } - try { - parent::getChildren(); - return \true; - } catch (\UnexpectedValueException) { - // If directory is unreadable and finder is set to ignore it, skip children - return \false; - } - } - /** - * @throws AccessDeniedException - */ - public function getChildren() : \RecursiveDirectoryIterator - { - try { - $children = parent::getChildren(); - if ($children instanceof self) { - // parent method will call the constructor with default arguments, so unreadable dirs won't be ignored anymore - $children->ignoreUnreadableDirs = $this->ignoreUnreadableDirs; - // performance optimization to avoid redoing the same work in all children - $children->rootPath = $this->rootPath; - } - return $children; - } catch (\UnexpectedValueException $e) { - throw new AccessDeniedException($e->getMessage(), $e->getCode(), $e); - } - } - public function next() : void - { - $this->ignoreFirstRewind = \false; - parent::next(); - } - public function rewind() : void - { - // some streams like FTP are not rewindable, ignore the first rewind after creation, - // as newly created DirectoryIterator does not need to be rewound - if ($this->ignoreFirstRewind) { - $this->ignoreFirstRewind = \false; - return; - } - parent::rewind(); - } -} diff --git a/vendor/prefixed/symfony/finder/Iterator/SizeRangeFilterIterator.php b/vendor/prefixed/symfony/finder/Iterator/SizeRangeFilterIterator.php deleted file mode 100644 index e123133..0000000 --- a/vendor/prefixed/symfony/finder/Iterator/SizeRangeFilterIterator.php +++ /dev/null @@ -1,50 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator; - -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\Comparator\NumberComparator; -/** - * SizeRangeFilterIterator filters out files that are not in the given size range. - * - * @author Fabien Potencier - * - * @extends \FilterIterator - */ -class SizeRangeFilterIterator extends \FilterIterator -{ - private array $comparators = []; - /** - * @param \Iterator $iterator - * @param NumberComparator[] $comparators - */ - public function __construct(\Iterator $iterator, array $comparators) - { - $this->comparators = $comparators; - parent::__construct($iterator); - } - /** - * Filters the iterator values. - */ - public function accept() : bool - { - $fileinfo = $this->current(); - if (!$fileinfo->isFile()) { - return \true; - } - $filesize = $fileinfo->getSize(); - foreach ($this->comparators as $compare) { - if (!$compare->test($filesize)) { - return \false; - } - } - return \true; - } -} diff --git a/vendor/prefixed/symfony/finder/Iterator/SortableIterator.php b/vendor/prefixed/symfony/finder/Iterator/SortableIterator.php deleted file mode 100644 index 1f4d0db..0000000 --- a/vendor/prefixed/symfony/finder/Iterator/SortableIterator.php +++ /dev/null @@ -1,103 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator; - -/** - * SortableIterator applies a sort on a given Iterator. - * - * @author Fabien Potencier - * - * @implements \IteratorAggregate - */ -class SortableIterator implements \IteratorAggregate -{ - public const SORT_BY_NONE = 0; - public const SORT_BY_NAME = 1; - public const SORT_BY_TYPE = 2; - public const SORT_BY_ACCESSED_TIME = 3; - public const SORT_BY_CHANGED_TIME = 4; - public const SORT_BY_MODIFIED_TIME = 5; - public const SORT_BY_NAME_NATURAL = 6; - public const SORT_BY_NAME_CASE_INSENSITIVE = 7; - public const SORT_BY_NAME_NATURAL_CASE_INSENSITIVE = 8; - public const SORT_BY_EXTENSION = 9; - public const SORT_BY_SIZE = 10; - /** @var \Traversable */ - private \Traversable $iterator; - private \Closure|int $sort; - /** - * @param \Traversable $iterator - * @param int|callable $sort The sort type (SORT_BY_NAME, SORT_BY_TYPE, or a PHP callback) - * - * @throws \InvalidArgumentException - */ - public function __construct(\Traversable $iterator, int|callable $sort, bool $reverseOrder = \false) - { - $this->iterator = $iterator; - $order = $reverseOrder ? -1 : 1; - if (self::SORT_BY_NAME === $sort) { - $this->sort = static fn(\SplFileInfo $a, \SplFileInfo $b) => $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); - } elseif (self::SORT_BY_NAME_NATURAL === $sort) { - $this->sort = static fn(\SplFileInfo $a, \SplFileInfo $b) => $order * strnatcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); - } elseif (self::SORT_BY_NAME_CASE_INSENSITIVE === $sort) { - $this->sort = static fn(\SplFileInfo $a, \SplFileInfo $b) => $order * strcasecmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); - } elseif (self::SORT_BY_NAME_NATURAL_CASE_INSENSITIVE === $sort) { - $this->sort = static fn(\SplFileInfo $a, \SplFileInfo $b) => $order * strnatcasecmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); - } elseif (self::SORT_BY_TYPE === $sort) { - $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use($order) { - if ($a->isDir() && $b->isFile()) { - return -$order; - } elseif ($a->isFile() && $b->isDir()) { - return $order; - } - return $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); - }; - } elseif (self::SORT_BY_ACCESSED_TIME === $sort) { - $this->sort = static fn(\SplFileInfo $a, \SplFileInfo $b) => $order * ($a->getATime() - $b->getATime()); - } elseif (self::SORT_BY_CHANGED_TIME === $sort) { - $this->sort = static fn(\SplFileInfo $a, \SplFileInfo $b) => $order * ($a->getCTime() - $b->getCTime()); - } elseif (self::SORT_BY_MODIFIED_TIME === $sort) { - $this->sort = static fn(\SplFileInfo $a, \SplFileInfo $b) => $order * ($a->getMTime() - $b->getMTime()); - } elseif (self::SORT_BY_EXTENSION === $sort) { - $this->sort = static fn(\SplFileInfo $a, \SplFileInfo $b) => $order * strnatcmp($a->getExtension(), $b->getExtension()); - } elseif (self::SORT_BY_SIZE === $sort) { - $this->sort = static fn(\SplFileInfo $a, \SplFileInfo $b) => $order * ($a->getSize() - $b->getSize()); - } elseif (self::SORT_BY_NONE === $sort) { - $this->sort = $order; - } elseif (\is_callable($sort)) { - $this->sort = $reverseOrder ? static fn(\SplFileInfo $a, \SplFileInfo $b) => -$sort($a, $b) : $sort(...); - } else { - throw new \InvalidArgumentException('The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.'); - } - } - public function getIterator() : \Traversable - { - if (1 === $this->sort) { - yield from $this->iterator; - return; - } - $keys = $values = []; - foreach ($this->iterator as $key => $value) { - $keys[] = $key; - $values[] = $value; - } - if (-1 === $this->sort) { - for ($i = \count($values) - 1; $i >= 0; --$i) { - (yield $keys[$i] => $values[$i]); - } - return; - } - uasort($values, $this->sort); - foreach ($values as $i => $v) { - (yield $keys[$i] => $v); - } - } -} diff --git a/vendor/prefixed/symfony/finder/Iterator/VcsIgnoredFilterIterator.php b/vendor/prefixed/symfony/finder/Iterator/VcsIgnoredFilterIterator.php deleted file mode 100644 index d3f0ced..0000000 --- a/vendor/prefixed/symfony/finder/Iterator/VcsIgnoredFilterIterator.php +++ /dev/null @@ -1,129 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder\Iterator; - -use Matomo\Dependencies\McpServer\Symfony\Component\Finder\Gitignore; -/** - * @extends \FilterIterator - */ -final class VcsIgnoredFilterIterator extends \FilterIterator -{ - private string $baseDir; - /** - * @var array - */ - private array $gitignoreFilesCache = []; - /** - * @var array - */ - private array $ignoredPathsCache = []; - /** - * @param \Iterator $iterator - */ - public function __construct(\Iterator $iterator, string $baseDir) - { - $this->baseDir = $this->normalizePath($baseDir); - foreach ([$this->baseDir, ...$this->parentDirectoriesUpwards($this->baseDir)] as $directory) { - if (@is_dir("{$directory}/.git")) { - $this->baseDir = $directory; - break; - } - } - parent::__construct($iterator); - } - public function accept() : bool - { - $file = $this->current(); - $fileRealPath = $this->normalizePath($file->getRealPath()); - return !$this->isIgnored($fileRealPath); - } - private function isIgnored(string $fileRealPath) : bool - { - if (is_dir($fileRealPath) && !str_ends_with($fileRealPath, '/')) { - $fileRealPath .= '/'; - } - if (isset($this->ignoredPathsCache[$fileRealPath])) { - return $this->ignoredPathsCache[$fileRealPath]; - } - $ignored = \false; - foreach ($this->parentDirectoriesDownwards($fileRealPath) as $parentDirectory) { - if ($this->isIgnored($parentDirectory)) { - // rules in ignored directories are ignored, no need to check further. - break; - } - $fileRelativePath = substr($fileRealPath, \strlen($parentDirectory) + 1); - if (null === ($regexps = $this->readGitignoreFile("{$parentDirectory}/.gitignore"))) { - continue; - } - [$exclusionRegex, $inclusionRegex] = $regexps; - if (preg_match($exclusionRegex, $fileRelativePath)) { - $ignored = \true; - continue; - } - if (preg_match($inclusionRegex, $fileRelativePath)) { - $ignored = \false; - } - } - return $this->ignoredPathsCache[$fileRealPath] = $ignored; - } - /** - * @return list - */ - private function parentDirectoriesUpwards(string $from) : array - { - $parentDirectories = []; - $parentDirectory = $from; - while (\true) { - $newParentDirectory = \dirname($parentDirectory); - // dirname('/') = '/' - if ($newParentDirectory === $parentDirectory) { - break; - } - $parentDirectories[] = $parentDirectory = $newParentDirectory; - } - return $parentDirectories; - } - private function parentDirectoriesUpTo(string $from, string $upTo) : array - { - return array_filter($this->parentDirectoriesUpwards($from), static fn(string $directory): bool => str_starts_with($directory, $upTo)); - } - /** - * @return list - */ - private function parentDirectoriesDownwards(string $fileRealPath) : array - { - return array_reverse($this->parentDirectoriesUpTo($fileRealPath, $this->baseDir)); - } - /** - * @return array{0: string, 1: string}|null - */ - private function readGitignoreFile(string $path) : ?array - { - if (\array_key_exists($path, $this->gitignoreFilesCache)) { - return $this->gitignoreFilesCache[$path]; - } - if (!file_exists($path)) { - return $this->gitignoreFilesCache[$path] = null; - } - if (!is_file($path) || !is_readable($path)) { - throw new \RuntimeException("The \"ignoreVCSIgnored\" option cannot be used by the Finder as the \"{$path}\" file is not readable."); - } - $gitignoreFileContent = file_get_contents($path); - return $this->gitignoreFilesCache[$path] = [Gitignore::toRegex($gitignoreFileContent), Gitignore::toRegexMatchingNegatedPatterns($gitignoreFileContent)]; - } - private function normalizePath(string $path) : string - { - if ('\\' === \DIRECTORY_SEPARATOR) { - return str_replace('\\', '/', $path); - } - return $path; - } -} diff --git a/vendor/prefixed/symfony/finder/README.md b/vendor/prefixed/symfony/finder/README.md deleted file mode 100644 index 22bdeb9..0000000 --- a/vendor/prefixed/symfony/finder/README.md +++ /dev/null @@ -1,14 +0,0 @@ -Finder Component -================ - -The Finder component finds files and directories via an intuitive fluent -interface. - -Resources ---------- - - * [Documentation](https://symfony.com/doc/current/components/finder.html) - * [Contributing](https://symfony.com/doc/current/contributing/index.html) - * [Report issues](https://github.com/symfony/symfony/issues) and - [send Pull Requests](https://github.com/symfony/symfony/pulls) - in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/vendor/prefixed/symfony/finder/SplFileInfo.php b/vendor/prefixed/symfony/finder/SplFileInfo.php deleted file mode 100644 index 67d0caa..0000000 --- a/vendor/prefixed/symfony/finder/SplFileInfo.php +++ /dev/null @@ -1,76 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -namespace Matomo\Dependencies\McpServer\Symfony\Component\Finder; - -/** - * Extends \SplFileInfo to support relative paths. - * - * @author Fabien Potencier - */ -class SplFileInfo extends \SplFileInfo -{ - private string $relativePath; - private string $relativePathname; - /** - * @param string $file The file name - * @param string $relativePath The relative path - * @param string $relativePathname The relative path name - */ - public function __construct(string $file, string $relativePath, string $relativePathname) - { - parent::__construct($file); - $this->relativePath = $relativePath; - $this->relativePathname = $relativePathname; - } - /** - * Returns the relative path. - * - * This path does not contain the file name. - */ - public function getRelativePath() : string - { - return $this->relativePath; - } - /** - * Returns the relative path name. - * - * This path contains the file name. - */ - public function getRelativePathname() : string - { - return $this->relativePathname; - } - public function getFilenameWithoutExtension() : string - { - $filename = $this->getFilename(); - return pathinfo($filename, \PATHINFO_FILENAME); - } - /** - * Returns the contents of the file. - * - * @throws \RuntimeException - */ - public function getContents() : string - { - set_error_handler(function ($type, $msg) use(&$error) { - $error = $msg; - }); - try { - $content = file_get_contents($this->getPathname()); - } finally { - restore_error_handler(); - } - if (\false === $content) { - throw new \RuntimeException($error); - } - return $content; - } -} diff --git a/vendor/prefixed/symfony/finder/composer.json b/vendor/prefixed/symfony/finder/composer.json deleted file mode 100644 index d96057d..0000000 --- a/vendor/prefixed/symfony/finder/composer.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "symfony\/finder", - "type": "library", - "description": "Finds files and directories via an intuitive fluent interface", - "keywords": [], - "homepage": "https:\/\/symfony.com", - "license": "MIT", - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https:\/\/symfony.com\/contributors" - } - ], - "require": { - "php": ">=8.1" - }, - "require-dev": { - "symfony\/filesystem": "^6.0|^7.0" - }, - "autoload": { - "psr-4": { - "Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "\/Tests\/" - ] - }, - "minimum-stability": "dev" -} \ No newline at end of file diff --git a/vendor/prefixed/symfony/polyfill-uuid/Uuid.php b/vendor/prefixed/symfony/polyfill-uuid/Uuid.php index 27cbee6..59289fb 100644 --- a/vendor/prefixed/symfony/polyfill-uuid/Uuid.php +++ b/vendor/prefixed/symfony/polyfill-uuid/Uuid.php @@ -41,7 +41,7 @@ final class Uuid public static function uuid_create($uuid_type = \UUID_TYPE_DEFAULT) { if (!is_numeric($uuid_type) && null !== $uuid_type) { - trigger_error(sprintf('uuid_create() expects parameter 1 to be int, %s given', \gettype($uuid_type)), \E_USER_WARNING); + trigger_error(\sprintf('uuid_create() expects parameter 1 to be int, %s given', \gettype($uuid_type)), \E_USER_WARNING); return null; } switch ((int) $uuid_type) { @@ -53,18 +53,18 @@ public static function uuid_create($uuid_type = \UUID_TYPE_DEFAULT) case self::UUID_TYPE_DEFAULT: return self::uuid_generate_random(); default: - trigger_error(sprintf("Unknown/invalid UUID type '%d' requested, using default type instead", $uuid_type), \E_USER_WARNING); + trigger_error(\sprintf("Unknown/invalid UUID type '%d' requested, using default type instead", $uuid_type), \E_USER_WARNING); return self::uuid_generate_random(); } } public static function uuid_generate_md5($uuid_ns, $name) { if (!\is_string($uuid_ns = self::toString($uuid_ns))) { - trigger_error(sprintf('uuid_generate_md5() expects parameter 1 to be string, %s given', \gettype($uuid_ns)), \E_USER_WARNING); + trigger_error(\sprintf('uuid_generate_md5() expects parameter 1 to be string, %s given', \gettype($uuid_ns)), \E_USER_WARNING); return null; } if (!\is_string($name = self::toString($name))) { - trigger_error(sprintf('uuid_generate_md5() expects parameter 2 to be string, %s given', \gettype($name)), \E_USER_WARNING); + trigger_error(\sprintf('uuid_generate_md5() expects parameter 2 to be string, %s given', \gettype($name)), \E_USER_WARNING); return null; } if (!self::isValid($uuid_ns)) { @@ -74,7 +74,7 @@ public static function uuid_generate_md5($uuid_ns, $name) throw new \ValueError('uuid_generate_md5(): Argument #1 ($uuid_ns) UUID expected'); } $hash = md5(hex2bin(str_replace('-', '', $uuid_ns)) . $name); - return sprintf( + return \sprintf( '%08s-%04s-3%03s-%04x-%012s', // 32 bits for "time_low" substr($hash, 0, 8), @@ -94,11 +94,11 @@ public static function uuid_generate_md5($uuid_ns, $name) public static function uuid_generate_sha1($uuid_ns, $name) { if (!\is_string($uuid_ns = self::toString($uuid_ns))) { - trigger_error(sprintf('uuid_generate_sha1() expects parameter 1 to be string, %s given', \gettype($uuid_ns)), \E_USER_WARNING); + trigger_error(\sprintf('uuid_generate_sha1() expects parameter 1 to be string, %s given', \gettype($uuid_ns)), \E_USER_WARNING); return null; } if (!\is_string($name = self::toString($name))) { - trigger_error(sprintf('uuid_generate_sha1() expects parameter 2 to be string, %s given', \gettype($name)), \E_USER_WARNING); + trigger_error(\sprintf('uuid_generate_sha1() expects parameter 2 to be string, %s given', \gettype($name)), \E_USER_WARNING); return null; } if (!self::isValid($uuid_ns)) { @@ -108,7 +108,7 @@ public static function uuid_generate_sha1($uuid_ns, $name) throw new \ValueError('uuid_generate_sha1(): Argument #1 ($uuid_ns) UUID expected'); } $hash = sha1(hex2bin(str_replace('-', '', $uuid_ns)) . $name); - return sprintf( + return \sprintf( '%08s-%04s-5%03s-%04x-%012s', // 32 bits for "time_low" substr($hash, 0, 8), @@ -130,7 +130,7 @@ public static function uuid_generate_sha1($uuid_ns, $name) public static function uuid_is_valid($uuid) { if (!\is_string($uuid = self::toString($uuid))) { - trigger_error(sprintf('uuid_is_valid() expects parameter 1 to be string, %s given', \gettype($uuid)), \E_USER_WARNING); + trigger_error(\sprintf('uuid_is_valid() expects parameter 1 to be string, %s given', \gettype($uuid)), \E_USER_WARNING); return null; } return self::isValid($uuid); @@ -138,11 +138,11 @@ public static function uuid_is_valid($uuid) public static function uuid_compare($uuid1, $uuid2) { if (!\is_string($uuid1 = self::toString($uuid1))) { - trigger_error(sprintf('uuid_compare() expects parameter 1 to be string, %s given', \gettype($uuid1)), \E_USER_WARNING); + trigger_error(\sprintf('uuid_compare() expects parameter 1 to be string, %s given', \gettype($uuid1)), \E_USER_WARNING); return null; } if (!\is_string($uuid2 = self::toString($uuid2))) { - trigger_error(sprintf('uuid_compare() expects parameter 2 to be string, %s given', \gettype($uuid2)), \E_USER_WARNING); + trigger_error(\sprintf('uuid_compare() expects parameter 2 to be string, %s given', \gettype($uuid2)), \E_USER_WARNING); return null; } if (!self::isValid($uuid1)) { @@ -162,7 +162,7 @@ public static function uuid_compare($uuid1, $uuid2) public static function uuid_is_null($uuid) { if (!\is_string($uuid = self::toString($uuid))) { - trigger_error(sprintf('uuid_is_null() expects parameter 1 to be string, %s given', \gettype($uuid)), \E_USER_WARNING); + trigger_error(\sprintf('uuid_is_null() expects parameter 1 to be string, %s given', \gettype($uuid)), \E_USER_WARNING); return null; } if (80000 <= \PHP_VERSION_ID && !self::isValid($uuid)) { @@ -173,7 +173,7 @@ public static function uuid_is_null($uuid) public static function uuid_type($uuid) { if (!\is_string($uuid = self::toString($uuid))) { - trigger_error(sprintf('uuid_type() expects parameter 1 to be string, %s given', \gettype($uuid)), \E_USER_WARNING); + trigger_error(\sprintf('uuid_type() expects parameter 1 to be string, %s given', \gettype($uuid)), \E_USER_WARNING); return null; } if ('00000000-0000-0000-0000-000000000000' === $uuid) { @@ -190,7 +190,7 @@ public static function uuid_type($uuid) public static function uuid_variant($uuid) { if (!\is_string($uuid = self::toString($uuid))) { - trigger_error(sprintf('uuid_variant() expects parameter 1 to be string, %s given', \gettype($uuid)), \E_USER_WARNING); + trigger_error(\sprintf('uuid_variant() expects parameter 1 to be string, %s given', \gettype($uuid)), \E_USER_WARNING); return null; } if ('00000000-0000-0000-0000-000000000000' === $uuid) { @@ -216,7 +216,7 @@ public static function uuid_variant($uuid) public static function uuid_time($uuid) { if (!\is_string($uuid = self::toString($uuid))) { - trigger_error(sprintf('uuid_time() expects parameter 1 to be string, %s given', \gettype($uuid)), \E_USER_WARNING); + trigger_error(\sprintf('uuid_time() expects parameter 1 to be string, %s given', \gettype($uuid)), \E_USER_WARNING); return null; } $parsed = self::parse($uuid); @@ -237,7 +237,7 @@ public static function uuid_time($uuid) public static function uuid_mac($uuid) { if (!\is_string($uuid = self::toString($uuid))) { - trigger_error(sprintf('uuid_mac() expects parameter 1 to be string, %s given', \gettype($uuid)), \E_USER_WARNING); + trigger_error(\sprintf('uuid_mac() expects parameter 1 to be string, %s given', \gettype($uuid)), \E_USER_WARNING); return null; } $parsed = self::parse($uuid); @@ -252,7 +252,7 @@ public static function uuid_mac($uuid) public static function uuid_parse($uuid) { if (!\is_string($uuid = self::toString($uuid))) { - trigger_error(sprintf('uuid_parse() expects parameter 1 to be string, %s given', \gettype($uuid)), \E_USER_WARNING); + trigger_error(\sprintf('uuid_parse() expects parameter 1 to be string, %s given', \gettype($uuid)), \E_USER_WARNING); return null; } if (!self::isValid($uuid)) { @@ -266,7 +266,7 @@ public static function uuid_parse($uuid) public static function uuid_unparse($bytes) { if (!\is_string($bytes = self::toString($bytes))) { - trigger_error(sprintf('uuid_unparse() expects parameter 1 to be string, %s given', \gettype($bytes)), \E_USER_WARNING); + trigger_error(\sprintf('uuid_unparse() expects parameter 1 to be string, %s given', \gettype($bytes)), \E_USER_WARNING); return null; } if (16 !== \strlen($bytes)) { @@ -284,7 +284,7 @@ public static function uuid_unparse($bytes) private static function uuid_generate_random() { $uuid = bin2hex(random_bytes(16)); - return sprintf( + return \sprintf( '%08s-%04s-4%03s-%04x-%012s', // 32 bits for "time_low" substr($uuid, 0, 8), @@ -325,14 +325,14 @@ private static function uuid_generate_time() if (\function_exists('apcu_fetch')) { $node = apcu_fetch('__symfony_uuid_node'); if (\false === $node) { - $node = sprintf('%06x%06x', random_int(0, 0xffffff) | 0x10000, random_int(0, 0xffffff)); + $node = \sprintf('%06x%06x', random_int(0, 0xffffff) | 0x10000, random_int(0, 0xffffff)); apcu_store('__symfony_uuid_node', $node); } } else { - $node = sprintf('%06x%06x', random_int(0, 0xffffff) | 0x10000, random_int(0, 0xffffff)); + $node = \sprintf('%06x%06x', random_int(0, 0xffffff) | 0x10000, random_int(0, 0xffffff)); } } - return sprintf( + return \sprintf( '%08s-%04s-1%03s-%04x-%012s', // 32 bits for "time_low" substr($time, -8), diff --git a/vendor/prefixed/vendor/autoload.php b/vendor/prefixed/vendor/autoload.php index f4778f1..74a52ab 100644 --- a/vendor/prefixed/vendor/autoload.php +++ b/vendor/prefixed/vendor/autoload.php @@ -22,4 +22,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInitca6eb2087c12f87e6297cb3c15f15c76::getLoader(); +return ComposerAutoloaderInit8b3681e24fa67a5543f8921436dddf2a::getLoader(); diff --git a/vendor/prefixed/vendor/composer/autoload_classmap.php b/vendor/prefixed/vendor/composer/autoload_classmap.php index 981f13a..4c4012c 100644 --- a/vendor/prefixed/vendor/composer/autoload_classmap.php +++ b/vendor/prefixed/vendor/composer/autoload_classmap.php @@ -69,6 +69,22 @@ 'Matomo\\Dependencies\\McpServer\\Mcp\\Capability\\Registry\\ResourceTemplateReference' => $baseDir . '/mcp/sdk/src/Capability/Registry/ResourceTemplateReference.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Capability\\Registry\\ToolReference' => $baseDir . '/mcp/sdk/src/Capability/Registry/ToolReference.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Capability\\Tool\\NameValidator' => $baseDir . '/mcp/sdk/src/Capability/Tool/NameValidator.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client' => $baseDir . '/mcp/sdk/src/Client.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Builder' => $baseDir . '/mcp/sdk/src/Client/Builder.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Configuration' => $baseDir . '/mcp/sdk/src/Client/Configuration.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Handler\\Notification\\LoggingNotificationHandler' => $baseDir . '/mcp/sdk/src/Client/Handler/Notification/LoggingNotificationHandler.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Handler\\Notification\\NotificationHandlerInterface' => $baseDir . '/mcp/sdk/src/Client/Handler/Notification/NotificationHandlerInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Handler\\Notification\\ProgressNotificationHandler' => $baseDir . '/mcp/sdk/src/Client/Handler/Notification/ProgressNotificationHandler.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Handler\\Request\\RequestHandlerInterface' => $baseDir . '/mcp/sdk/src/Client/Handler/Request/RequestHandlerInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Handler\\Request\\SamplingCallbackInterface' => $baseDir . '/mcp/sdk/src/Client/Handler/Request/SamplingCallbackInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Handler\\Request\\SamplingRequestHandler' => $baseDir . '/mcp/sdk/src/Client/Handler/Request/SamplingRequestHandler.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Protocol' => $baseDir . '/mcp/sdk/src/Client/Protocol.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\State\\ClientState' => $baseDir . '/mcp/sdk/src/Client/State/ClientState.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\State\\ClientStateInterface' => $baseDir . '/mcp/sdk/src/Client/State/ClientStateInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Transport\\BaseTransport' => $baseDir . '/mcp/sdk/src/Client/Transport/BaseTransport.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Transport\\HttpTransport' => $baseDir . '/mcp/sdk/src/Client/Transport/HttpTransport.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Transport\\StdioTransport' => $baseDir . '/mcp/sdk/src/Client/Transport/StdioTransport.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Transport\\TransportInterface' => $baseDir . '/mcp/sdk/src/Client/Transport/TransportInterface.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Event\\ErrorEvent' => $baseDir . '/mcp/sdk/src/Event/ErrorEvent.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Event\\NotificationEvent' => $baseDir . '/mcp/sdk/src/Event/NotificationEvent.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Event\\PromptListChangedEvent' => $baseDir . '/mcp/sdk/src/Event/PromptListChangedEvent.php', @@ -79,7 +95,9 @@ 'Matomo\\Dependencies\\McpServer\\Mcp\\Event\\ToolListChangedEvent' => $baseDir . '/mcp/sdk/src/Event/ToolListChangedEvent.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\BadMethodCallException' => $baseDir . '/mcp/sdk/src/Exception/BadMethodCallException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ClientException' => $baseDir . '/mcp/sdk/src/Exception/ClientException.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ClientRegistrationException' => $baseDir . '/mcp/sdk/src/Exception/ClientRegistrationException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ConfigurationException' => $baseDir . '/mcp/sdk/src/Exception/ConfigurationException.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ConnectionException' => $baseDir . '/mcp/sdk/src/Exception/ConnectionException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ContainerException' => $baseDir . '/mcp/sdk/src/Exception/ContainerException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\Exception' => $baseDir . '/mcp/sdk/src/Exception/Exception.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ExceptionInterface' => $baseDir . '/mcp/sdk/src/Exception/ExceptionInterface.php', @@ -92,10 +110,13 @@ 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\PromptGetException' => $baseDir . '/mcp/sdk/src/Exception/PromptGetException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\PromptNotFoundException' => $baseDir . '/mcp/sdk/src/Exception/PromptNotFoundException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\RegistryException' => $baseDir . '/mcp/sdk/src/Exception/RegistryException.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\RequestException' => $baseDir . '/mcp/sdk/src/Exception/RequestException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ResourceNotFoundException' => $baseDir . '/mcp/sdk/src/Exception/ResourceNotFoundException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ResourceReadException' => $baseDir . '/mcp/sdk/src/Exception/ResourceReadException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\RuntimeException' => $baseDir . '/mcp/sdk/src/Exception/RuntimeException.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\SamplingException' => $baseDir . '/mcp/sdk/src/Exception/SamplingException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ServiceNotFoundException' => $baseDir . '/mcp/sdk/src/Exception/ServiceNotFoundException.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\TimeoutException' => $baseDir . '/mcp/sdk/src/Exception/TimeoutException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ToolCallException' => $baseDir . '/mcp/sdk/src/Exception/ToolCallException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ToolNotFoundException' => $baseDir . '/mcp/sdk/src/Exception/ToolNotFoundException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\JsonRpc\\MessageFactory' => $baseDir . '/mcp/sdk/src/JsonRpc/MessageFactory.php', @@ -115,9 +136,11 @@ 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Elicitation\\BooleanSchemaDefinition' => $baseDir . '/mcp/sdk/src/Schema/Elicitation/BooleanSchemaDefinition.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Elicitation\\ElicitationSchema' => $baseDir . '/mcp/sdk/src/Schema/Elicitation/ElicitationSchema.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Elicitation\\EnumSchemaDefinition' => $baseDir . '/mcp/sdk/src/Schema/Elicitation/EnumSchemaDefinition.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Elicitation\\MultiSelectEnumSchemaDefinition' => $baseDir . '/mcp/sdk/src/Schema/Elicitation/MultiSelectEnumSchemaDefinition.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Elicitation\\NumberSchemaDefinition' => $baseDir . '/mcp/sdk/src/Schema/Elicitation/NumberSchemaDefinition.php', - 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Elicitation\\PrimitiveSchemaDefinition' => $baseDir . '/mcp/sdk/src/Schema/Elicitation/PrimitiveSchemaDefinition.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Elicitation\\StringSchemaDefinition' => $baseDir . '/mcp/sdk/src/Schema/Elicitation/StringSchemaDefinition.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Elicitation\\TitledEnumSchemaDefinition' => $baseDir . '/mcp/sdk/src/Schema/Elicitation/TitledEnumSchemaDefinition.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Elicitation\\TitledMultiSelectEnumSchemaDefinition' => $baseDir . '/mcp/sdk/src/Schema/Elicitation/TitledMultiSelectEnumSchemaDefinition.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Enum\\ElicitAction' => $baseDir . '/mcp/sdk/src/Schema/Enum/ElicitAction.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Enum\\LoggingLevel' => $baseDir . '/mcp/sdk/src/Schema/Enum/LoggingLevel.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Enum\\ProtocolVersion' => $baseDir . '/mcp/sdk/src/Schema/Enum/ProtocolVersion.php', @@ -212,13 +235,30 @@ 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Session\\InMemorySessionStore' => $baseDir . '/mcp/sdk/src/Server/Session/InMemorySessionStore.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Session\\Psr16SessionStore' => $baseDir . '/mcp/sdk/src/Server/Session/Psr16SessionStore.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Session\\Session' => $baseDir . '/mcp/sdk/src/Server/Session/Session.php', - 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Session\\SessionFactory' => $baseDir . '/mcp/sdk/src/Server/Session/SessionFactory.php', - 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Session\\SessionFactoryInterface' => $baseDir . '/mcp/sdk/src/Server/Session/SessionFactoryInterface.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Session\\SessionInterface' => $baseDir . '/mcp/sdk/src/Server/Session/SessionInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Session\\SessionManager' => $baseDir . '/mcp/sdk/src/Server/Session/SessionManager.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Session\\SessionManagerInterface' => $baseDir . '/mcp/sdk/src/Server/Session/SessionManagerInterface.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Session\\SessionStoreInterface' => $baseDir . '/mcp/sdk/src/Server/Session/SessionStoreInterface.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\BaseTransport' => $baseDir . '/mcp/sdk/src/Server/Transport/BaseTransport.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\CallbackStream' => $baseDir . '/mcp/sdk/src/Server/Transport/CallbackStream.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\MiddlewareRequestHandler' => $baseDir . '/mcp/sdk/src/Server/Transport/Http/MiddlewareRequestHandler.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\Middleware\\AuthorizationMiddleware' => $baseDir . '/mcp/sdk/src/Server/Transport/Http/Middleware/AuthorizationMiddleware.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\Middleware\\ClientRegistrationMiddleware' => $baseDir . '/mcp/sdk/src/Server/Transport/Http/Middleware/ClientRegistrationMiddleware.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\Middleware\\OAuthProxyMiddleware' => $baseDir . '/mcp/sdk/src/Server/Transport/Http/Middleware/OAuthProxyMiddleware.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\Middleware\\OAuthRequestMetaMiddleware' => $baseDir . '/mcp/sdk/src/Server/Transport/Http/Middleware/OAuthRequestMetaMiddleware.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\Middleware\\ProtectedResourceMetadataMiddleware' => $baseDir . '/mcp/sdk/src/Server/Transport/Http/Middleware/ProtectedResourceMetadataMiddleware.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\AuthorizationResult' => $baseDir . '/mcp/sdk/src/Server/Transport/Http/OAuth/AuthorizationResult.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\AuthorizationTokenValidatorInterface' => $baseDir . '/mcp/sdk/src/Server/Transport/Http/OAuth/AuthorizationTokenValidatorInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\ClientRegistrarInterface' => $baseDir . '/mcp/sdk/src/Server/Transport/Http/OAuth/ClientRegistrarInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\JwksProvider' => $baseDir . '/mcp/sdk/src/Server/Transport/Http/OAuth/JwksProvider.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\JwksProviderInterface' => $baseDir . '/mcp/sdk/src/Server/Transport/Http/OAuth/JwksProviderInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\JwtTokenValidator' => $baseDir . '/mcp/sdk/src/Server/Transport/Http/OAuth/JwtTokenValidator.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\LenientOidcDiscoveryMetadataPolicy' => $baseDir . '/mcp/sdk/src/Server/Transport/Http/OAuth/LenientOidcDiscoveryMetadataPolicy.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\OidcDiscovery' => $baseDir . '/mcp/sdk/src/Server/Transport/Http/OAuth/OidcDiscovery.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\OidcDiscoveryInterface' => $baseDir . '/mcp/sdk/src/Server/Transport/Http/OAuth/OidcDiscoveryInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\OidcDiscoveryMetadataPolicyInterface' => $baseDir . '/mcp/sdk/src/Server/Transport/Http/OAuth/OidcDiscoveryMetadataPolicyInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\ProtectedResourceMetadata' => $baseDir . '/mcp/sdk/src/Server/Transport/Http/OAuth/ProtectedResourceMetadata.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\StrictOidcDiscoveryMetadataPolicy' => $baseDir . '/mcp/sdk/src/Server/Transport/Http/OAuth/StrictOidcDiscoveryMetadataPolicy.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\InMemoryTransport' => $baseDir . '/mcp/sdk/src/Server/Transport/InMemoryTransport.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\ManagesTransportCallbacks' => $baseDir . '/mcp/sdk/src/Server/Transport/ManagesTransportCallbacks.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\StdioTransport' => $baseDir . '/mcp/sdk/src/Server/Transport/StdioTransport.php', @@ -534,6 +574,10 @@ 'Matomo\\Dependencies\\McpServer\\PHPStan\\PhpDocParser\\Printer\\Differ' => $baseDir . '/phpstan/phpdoc-parser/src/Printer/Differ.php', 'Matomo\\Dependencies\\McpServer\\PHPStan\\PhpDocParser\\Printer\\Printer' => $baseDir . '/phpstan/phpdoc-parser/src/Printer/Printer.php', 'Matomo\\Dependencies\\McpServer\\Psr\\Clock\\ClockInterface' => $baseDir . '/psr/clock/src/ClockInterface.php', + 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Client\\ClientExceptionInterface' => $baseDir . '/psr/http-client/src/ClientExceptionInterface.php', + 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Client\\ClientInterface' => $baseDir . '/psr/http-client/src/ClientInterface.php', + 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Client\\NetworkExceptionInterface' => $baseDir . '/psr/http-client/src/NetworkExceptionInterface.php', + 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Client\\RequestExceptionInterface' => $baseDir . '/psr/http-client/src/RequestExceptionInterface.php', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\MessageInterface' => $baseDir . '/psr/http-message/src/MessageInterface.php', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\RequestFactoryInterface' => $baseDir . '/psr/http-factory/src/RequestFactoryInterface.php', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\RequestInterface' => $baseDir . '/psr/http-message/src/RequestInterface.php', @@ -549,29 +593,6 @@ 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\UriInterface' => $baseDir . '/psr/http-message/src/UriInterface.php', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Server\\MiddlewareInterface' => $baseDir . '/psr/http-server-middleware/src/MiddlewareInterface.php', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Server\\RequestHandlerInterface' => $baseDir . '/psr/http-server-handler/src/RequestHandlerInterface.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Comparator\\Comparator' => $baseDir . '/symfony/finder/Comparator/Comparator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Comparator\\DateComparator' => $baseDir . '/symfony/finder/Comparator/DateComparator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Comparator\\NumberComparator' => $baseDir . '/symfony/finder/Comparator/NumberComparator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Exception\\AccessDeniedException' => $baseDir . '/symfony/finder/Exception/AccessDeniedException.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Exception\\DirectoryNotFoundException' => $baseDir . '/symfony/finder/Exception/DirectoryNotFoundException.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Finder' => $baseDir . '/symfony/finder/Finder.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Gitignore' => $baseDir . '/symfony/finder/Gitignore.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Glob' => $baseDir . '/symfony/finder/Glob.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\CustomFilterIterator' => $baseDir . '/symfony/finder/Iterator/CustomFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\DateRangeFilterIterator' => $baseDir . '/symfony/finder/Iterator/DateRangeFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\DepthRangeFilterIterator' => $baseDir . '/symfony/finder/Iterator/DepthRangeFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\ExcludeDirectoryFilterIterator' => $baseDir . '/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\FileTypeFilterIterator' => $baseDir . '/symfony/finder/Iterator/FileTypeFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\FilecontentFilterIterator' => $baseDir . '/symfony/finder/Iterator/FilecontentFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\FilenameFilterIterator' => $baseDir . '/symfony/finder/Iterator/FilenameFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\LazyIterator' => $baseDir . '/symfony/finder/Iterator/LazyIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\MultiplePcreFilterIterator' => $baseDir . '/symfony/finder/Iterator/MultiplePcreFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\PathFilterIterator' => $baseDir . '/symfony/finder/Iterator/PathFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\RecursiveDirectoryIterator' => $baseDir . '/symfony/finder/Iterator/RecursiveDirectoryIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\SizeRangeFilterIterator' => $baseDir . '/symfony/finder/Iterator/SizeRangeFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\SortableIterator' => $baseDir . '/symfony/finder/Iterator/SortableIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\VcsIgnoredFilterIterator' => $baseDir . '/symfony/finder/Iterator/VcsIgnoredFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\SplFileInfo' => $baseDir . '/symfony/finder/SplFileInfo.php', 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Uid\\AbstractUid' => $baseDir . '/symfony/uid/AbstractUid.php', 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Uid\\BinaryUtil' => $baseDir . '/symfony/uid/BinaryUtil.php', 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Uid\\Command\\GenerateUlidCommand' => $baseDir . '/symfony/uid/Command/GenerateUlidCommand.php', @@ -623,16 +644,16 @@ 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ImplementsFactory' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ImplementsFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\MethodFactory' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MethodFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\MethodParameterFactory' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MethodParameterFactory.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\MixinFactory' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MixinFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PHPStanFactory' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PHPStanFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ParamFactory' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ParamFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PropertyFactory' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PropertyFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PropertyReadFactory' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PropertyReadFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PropertyWriteFactory' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PropertyWriteFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ReturnFactory' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ReturnFactory.php', - 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\StaticMethod' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php', - 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\TemplateExtendsFactory' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateExtendsFactory.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\TemplateCovariantFactory' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateCovariantFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\TemplateFactory' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateFactory.php', - 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\TemplateImplementsFactory' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateImplementsFactory.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ThrowsFactory' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ThrowsFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\VarFactory' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/VarFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\AlignFormatter' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php', @@ -665,7 +686,10 @@ 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Var_' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Version' => $baseDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Element' => $baseDir . '/phpdocumentor/reflection-common/src/Element.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Exception\\CannotCreateTag' => $baseDir . '/phpdocumentor/reflection-docblock/src/Exception/CannotCreateTag.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Exception\\ParserException' => $baseDir . '/phpdocumentor/reflection-docblock/src/Exception/ParserException.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Exception\\PcreException' => $baseDir . '/phpdocumentor/reflection-docblock/src/Exception/PcreException.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Exception\\ReflectionDocblockException' => $baseDir . '/phpdocumentor/reflection-docblock/src/Exception/ReflectionDocblockException.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\File' => $baseDir . '/phpdocumentor/reflection-common/src/File.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Fqsen' => $baseDir . '/phpdocumentor/reflection-common/src/Fqsen.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\FqsenResolver' => $baseDir . '/phpdocumentor/type-resolver/src/FqsenResolver.php', @@ -673,19 +697,26 @@ 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Project' => $baseDir . '/phpdocumentor/reflection-common/src/Project.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\ProjectFactory' => $baseDir . '/phpdocumentor/reflection-common/src/ProjectFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoType' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoType.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ArrayKey' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/ArrayKey.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ArrayShape' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/ArrayShape.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ArrayShapeItem' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/ArrayShapeItem.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\CallableArray' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/CallableArray.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\CallableString' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/CallableString.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ClassString' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/ClassString.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ClosedResource' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/ClosedResource.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\Conditional' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/Conditional.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ConditionalForParameter' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/ConditionalForParameter.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ConstExpression' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/ConstExpression.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\EnumString' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/EnumString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\False_' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/False_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\FloatValue' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/FloatValue.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\Generic' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/Generic.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\HtmlEscapedString' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/HtmlEscapedString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\IntMask' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/IntMask.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\IntMaskOf' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/IntMaskOf.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\IntegerRange' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/IntegerRange.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\IntegerValue' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/IntegerValue.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\InterfaceString' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/InterfaceString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\KeyOf' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/KeyOf.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ListShape' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/ListShape.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ListShapeItem' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/ListShapeItem.php', @@ -693,39 +724,49 @@ 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\LiteralString' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/LiteralString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\LowercaseString' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/LowercaseString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NegativeInteger' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/NegativeInteger.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NeverReturn' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/NeverReturn.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NeverReturns' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/NeverReturns.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NoReturn' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/NoReturn.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NonEmptyArray' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyArray.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NonEmptyList' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyList.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NonEmptyLowercaseString' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyLowercaseString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NonEmptyString' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyString.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NonFalsyString' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/NonFalsyString.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NonNegativeInteger' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/NonNegativeInteger.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NonPositiveInteger' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/NonPositiveInteger.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NonZeroInteger' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/NonZeroInteger.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NumericString' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/NumericString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\Numeric_' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/Numeric_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ObjectShape' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/ObjectShape.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ObjectShapeItem' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/ObjectShapeItem.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\OffsetAccess' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/OffsetAccess.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\OpenResource' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/OpenResource.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\PositiveInteger' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/PositiveInteger.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\PrivatePropertiesOf' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/PrivatePropertiesOf.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\PropertiesOf' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/PropertiesOf.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ProtectedPropertiesOf' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/ProtectedPropertiesOf.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\PublicPropertiesOf' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/PublicPropertiesOf.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\Scalar' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/Scalar.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ShapeItem' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/ShapeItem.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\StringValue' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/StringValue.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\TraitString' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/TraitString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\True_' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/True_.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\TruthyString' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/TruthyString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ValueOf' => $baseDir . '/phpdocumentor/type-resolver/src/PseudoTypes/ValueOf.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Type' => $baseDir . '/phpdocumentor/type-resolver/src/Type.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\TypeResolver' => $baseDir . '/phpdocumentor/type-resolver/src/TypeResolver.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\AbstractList' => $baseDir . '/phpdocumentor/type-resolver/src/Types/AbstractList.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\AggregatedType' => $baseDir . '/phpdocumentor/type-resolver/src/Types/AggregatedType.php', - 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\ArrayKey' => $baseDir . '/phpdocumentor/type-resolver/src/Types/ArrayKey.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Array_' => $baseDir . '/phpdocumentor/type-resolver/src/Types/Array_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Boolean' => $baseDir . '/phpdocumentor/type-resolver/src/Types/Boolean.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\CallableParameter' => $baseDir . '/phpdocumentor/type-resolver/src/Types/CallableParameter.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Callable_' => $baseDir . '/phpdocumentor/type-resolver/src/Types/Callable_.php', - 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\ClassString' => $baseDir . '/phpdocumentor/type-resolver/src/Types/ClassString.php', - 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Collection' => $baseDir . '/phpdocumentor/type-resolver/src/Types/Collection.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Compound' => $baseDir . '/phpdocumentor/type-resolver/src/Types/Compound.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Context' => $baseDir . '/phpdocumentor/type-resolver/src/Types/Context.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\ContextFactory' => $baseDir . '/phpdocumentor/type-resolver/src/Types/ContextFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Expression' => $baseDir . '/phpdocumentor/type-resolver/src/Types/Expression.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Float_' => $baseDir . '/phpdocumentor/type-resolver/src/Types/Float_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Integer' => $baseDir . '/phpdocumentor/type-resolver/src/Types/Integer.php', - 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\InterfaceString' => $baseDir . '/phpdocumentor/type-resolver/src/Types/InterfaceString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Intersection' => $baseDir . '/phpdocumentor/type-resolver/src/Types/Intersection.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Iterable_' => $baseDir . '/phpdocumentor/type-resolver/src/Types/Iterable_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Mixed_' => $baseDir . '/phpdocumentor/type-resolver/src/Types/Mixed_.php', @@ -735,7 +776,6 @@ 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Object_' => $baseDir . '/phpdocumentor/type-resolver/src/Types/Object_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Parent_' => $baseDir . '/phpdocumentor/type-resolver/src/Types/Parent_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Resource_' => $baseDir . '/phpdocumentor/type-resolver/src/Types/Resource_.php', - 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Scalar' => $baseDir . '/phpdocumentor/type-resolver/src/Types/Scalar.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Self_' => $baseDir . '/phpdocumentor/type-resolver/src/Types/Self_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Static_' => $baseDir . '/phpdocumentor/type-resolver/src/Types/Static_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\String_' => $baseDir . '/phpdocumentor/type-resolver/src/Types/String_.php', diff --git a/vendor/prefixed/vendor/composer/autoload_real.php b/vendor/prefixed/vendor/composer/autoload_real.php index 48fc12d..3ed1954 100644 --- a/vendor/prefixed/vendor/composer/autoload_real.php +++ b/vendor/prefixed/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInitca6eb2087c12f87e6297cb3c15f15c76 +class ComposerAutoloaderInit8b3681e24fa67a5543f8921436dddf2a { private static $loader; @@ -22,16 +22,16 @@ public static function getLoader() return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInitca6eb2087c12f87e6297cb3c15f15c76', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit8b3681e24fa67a5543f8921436dddf2a', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); - spl_autoload_unregister(array('ComposerAutoloaderInitca6eb2087c12f87e6297cb3c15f15c76', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit8b3681e24fa67a5543f8921436dddf2a', 'loadClassLoader')); require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInitca6eb2087c12f87e6297cb3c15f15c76::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit8b3681e24fa67a5543f8921436dddf2a::getInitializer($loader)); $loader->register(true); - $filesToLoad = \Composer\Autoload\ComposerStaticInitca6eb2087c12f87e6297cb3c15f15c76::$files; + $filesToLoad = \Composer\Autoload\ComposerStaticInit8b3681e24fa67a5543f8921436dddf2a::$files; $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; diff --git a/vendor/prefixed/vendor/composer/autoload_static.php b/vendor/prefixed/vendor/composer/autoload_static.php index cd7b53a..9a8a6cd 100644 --- a/vendor/prefixed/vendor/composer/autoload_static.php +++ b/vendor/prefixed/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInitca6eb2087c12f87e6297cb3c15f15c76 +class ComposerStaticInit8b3681e24fa67a5543f8921436dddf2a { public static $files = array ( 'c855ed707b6003bfa8b26e0244490be1' => __DIR__ . '/../..' . '/symfony/polyfill-uuid/bootstrap.php', @@ -74,6 +74,22 @@ class ComposerStaticInitca6eb2087c12f87e6297cb3c15f15c76 'Matomo\\Dependencies\\McpServer\\Mcp\\Capability\\Registry\\ResourceTemplateReference' => __DIR__ . '/../..' . '/mcp/sdk/src/Capability/Registry/ResourceTemplateReference.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Capability\\Registry\\ToolReference' => __DIR__ . '/../..' . '/mcp/sdk/src/Capability/Registry/ToolReference.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Capability\\Tool\\NameValidator' => __DIR__ . '/../..' . '/mcp/sdk/src/Capability/Tool/NameValidator.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client' => __DIR__ . '/../..' . '/mcp/sdk/src/Client.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Builder' => __DIR__ . '/../..' . '/mcp/sdk/src/Client/Builder.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Configuration' => __DIR__ . '/../..' . '/mcp/sdk/src/Client/Configuration.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Handler\\Notification\\LoggingNotificationHandler' => __DIR__ . '/../..' . '/mcp/sdk/src/Client/Handler/Notification/LoggingNotificationHandler.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Handler\\Notification\\NotificationHandlerInterface' => __DIR__ . '/../..' . '/mcp/sdk/src/Client/Handler/Notification/NotificationHandlerInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Handler\\Notification\\ProgressNotificationHandler' => __DIR__ . '/../..' . '/mcp/sdk/src/Client/Handler/Notification/ProgressNotificationHandler.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Handler\\Request\\RequestHandlerInterface' => __DIR__ . '/../..' . '/mcp/sdk/src/Client/Handler/Request/RequestHandlerInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Handler\\Request\\SamplingCallbackInterface' => __DIR__ . '/../..' . '/mcp/sdk/src/Client/Handler/Request/SamplingCallbackInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Handler\\Request\\SamplingRequestHandler' => __DIR__ . '/../..' . '/mcp/sdk/src/Client/Handler/Request/SamplingRequestHandler.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Protocol' => __DIR__ . '/../..' . '/mcp/sdk/src/Client/Protocol.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\State\\ClientState' => __DIR__ . '/../..' . '/mcp/sdk/src/Client/State/ClientState.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\State\\ClientStateInterface' => __DIR__ . '/../..' . '/mcp/sdk/src/Client/State/ClientStateInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Transport\\BaseTransport' => __DIR__ . '/../..' . '/mcp/sdk/src/Client/Transport/BaseTransport.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Transport\\HttpTransport' => __DIR__ . '/../..' . '/mcp/sdk/src/Client/Transport/HttpTransport.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Transport\\StdioTransport' => __DIR__ . '/../..' . '/mcp/sdk/src/Client/Transport/StdioTransport.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Client\\Transport\\TransportInterface' => __DIR__ . '/../..' . '/mcp/sdk/src/Client/Transport/TransportInterface.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Event\\ErrorEvent' => __DIR__ . '/../..' . '/mcp/sdk/src/Event/ErrorEvent.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Event\\NotificationEvent' => __DIR__ . '/../..' . '/mcp/sdk/src/Event/NotificationEvent.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Event\\PromptListChangedEvent' => __DIR__ . '/../..' . '/mcp/sdk/src/Event/PromptListChangedEvent.php', @@ -84,7 +100,9 @@ class ComposerStaticInitca6eb2087c12f87e6297cb3c15f15c76 'Matomo\\Dependencies\\McpServer\\Mcp\\Event\\ToolListChangedEvent' => __DIR__ . '/../..' . '/mcp/sdk/src/Event/ToolListChangedEvent.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\BadMethodCallException' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/BadMethodCallException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ClientException' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/ClientException.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ClientRegistrationException' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/ClientRegistrationException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ConfigurationException' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/ConfigurationException.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ConnectionException' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/ConnectionException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ContainerException' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/ContainerException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\Exception' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/Exception.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ExceptionInterface' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/ExceptionInterface.php', @@ -97,10 +115,13 @@ class ComposerStaticInitca6eb2087c12f87e6297cb3c15f15c76 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\PromptGetException' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/PromptGetException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\PromptNotFoundException' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/PromptNotFoundException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\RegistryException' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/RegistryException.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\RequestException' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/RequestException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ResourceNotFoundException' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/ResourceNotFoundException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ResourceReadException' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/ResourceReadException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\RuntimeException' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/RuntimeException.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\SamplingException' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/SamplingException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ServiceNotFoundException' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/ServiceNotFoundException.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\TimeoutException' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/TimeoutException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ToolCallException' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/ToolCallException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Exception\\ToolNotFoundException' => __DIR__ . '/../..' . '/mcp/sdk/src/Exception/ToolNotFoundException.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\JsonRpc\\MessageFactory' => __DIR__ . '/../..' . '/mcp/sdk/src/JsonRpc/MessageFactory.php', @@ -120,9 +141,11 @@ class ComposerStaticInitca6eb2087c12f87e6297cb3c15f15c76 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Elicitation\\BooleanSchemaDefinition' => __DIR__ . '/../..' . '/mcp/sdk/src/Schema/Elicitation/BooleanSchemaDefinition.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Elicitation\\ElicitationSchema' => __DIR__ . '/../..' . '/mcp/sdk/src/Schema/Elicitation/ElicitationSchema.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Elicitation\\EnumSchemaDefinition' => __DIR__ . '/../..' . '/mcp/sdk/src/Schema/Elicitation/EnumSchemaDefinition.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Elicitation\\MultiSelectEnumSchemaDefinition' => __DIR__ . '/../..' . '/mcp/sdk/src/Schema/Elicitation/MultiSelectEnumSchemaDefinition.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Elicitation\\NumberSchemaDefinition' => __DIR__ . '/../..' . '/mcp/sdk/src/Schema/Elicitation/NumberSchemaDefinition.php', - 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Elicitation\\PrimitiveSchemaDefinition' => __DIR__ . '/../..' . '/mcp/sdk/src/Schema/Elicitation/PrimitiveSchemaDefinition.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Elicitation\\StringSchemaDefinition' => __DIR__ . '/../..' . '/mcp/sdk/src/Schema/Elicitation/StringSchemaDefinition.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Elicitation\\TitledEnumSchemaDefinition' => __DIR__ . '/../..' . '/mcp/sdk/src/Schema/Elicitation/TitledEnumSchemaDefinition.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Elicitation\\TitledMultiSelectEnumSchemaDefinition' => __DIR__ . '/../..' . '/mcp/sdk/src/Schema/Elicitation/TitledMultiSelectEnumSchemaDefinition.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Enum\\ElicitAction' => __DIR__ . '/../..' . '/mcp/sdk/src/Schema/Enum/ElicitAction.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Enum\\LoggingLevel' => __DIR__ . '/../..' . '/mcp/sdk/src/Schema/Enum/LoggingLevel.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Schema\\Enum\\ProtocolVersion' => __DIR__ . '/../..' . '/mcp/sdk/src/Schema/Enum/ProtocolVersion.php', @@ -217,13 +240,30 @@ class ComposerStaticInitca6eb2087c12f87e6297cb3c15f15c76 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Session\\InMemorySessionStore' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Session/InMemorySessionStore.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Session\\Psr16SessionStore' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Session/Psr16SessionStore.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Session\\Session' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Session/Session.php', - 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Session\\SessionFactory' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Session/SessionFactory.php', - 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Session\\SessionFactoryInterface' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Session/SessionFactoryInterface.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Session\\SessionInterface' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Session/SessionInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Session\\SessionManager' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Session/SessionManager.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Session\\SessionManagerInterface' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Session/SessionManagerInterface.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Session\\SessionStoreInterface' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Session/SessionStoreInterface.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\BaseTransport' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/BaseTransport.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\CallbackStream' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/CallbackStream.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\MiddlewareRequestHandler' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/Http/MiddlewareRequestHandler.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\Middleware\\AuthorizationMiddleware' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/Http/Middleware/AuthorizationMiddleware.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\Middleware\\ClientRegistrationMiddleware' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/Http/Middleware/ClientRegistrationMiddleware.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\Middleware\\OAuthProxyMiddleware' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/Http/Middleware/OAuthProxyMiddleware.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\Middleware\\OAuthRequestMetaMiddleware' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/Http/Middleware/OAuthRequestMetaMiddleware.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\Middleware\\ProtectedResourceMetadataMiddleware' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/Http/Middleware/ProtectedResourceMetadataMiddleware.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\AuthorizationResult' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/Http/OAuth/AuthorizationResult.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\AuthorizationTokenValidatorInterface' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/Http/OAuth/AuthorizationTokenValidatorInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\ClientRegistrarInterface' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/Http/OAuth/ClientRegistrarInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\JwksProvider' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/Http/OAuth/JwksProvider.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\JwksProviderInterface' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/Http/OAuth/JwksProviderInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\JwtTokenValidator' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/Http/OAuth/JwtTokenValidator.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\LenientOidcDiscoveryMetadataPolicy' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/Http/OAuth/LenientOidcDiscoveryMetadataPolicy.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\OidcDiscovery' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/Http/OAuth/OidcDiscovery.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\OidcDiscoveryInterface' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/Http/OAuth/OidcDiscoveryInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\OidcDiscoveryMetadataPolicyInterface' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/Http/OAuth/OidcDiscoveryMetadataPolicyInterface.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\ProtectedResourceMetadata' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/Http/OAuth/ProtectedResourceMetadata.php', + 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\Http\\OAuth\\StrictOidcDiscoveryMetadataPolicy' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/Http/OAuth/StrictOidcDiscoveryMetadataPolicy.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\InMemoryTransport' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/InMemoryTransport.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\ManagesTransportCallbacks' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/ManagesTransportCallbacks.php', 'Matomo\\Dependencies\\McpServer\\Mcp\\Server\\Transport\\StdioTransport' => __DIR__ . '/../..' . '/mcp/sdk/src/Server/Transport/StdioTransport.php', @@ -539,6 +579,10 @@ class ComposerStaticInitca6eb2087c12f87e6297cb3c15f15c76 'Matomo\\Dependencies\\McpServer\\PHPStan\\PhpDocParser\\Printer\\Differ' => __DIR__ . '/../..' . '/phpstan/phpdoc-parser/src/Printer/Differ.php', 'Matomo\\Dependencies\\McpServer\\PHPStan\\PhpDocParser\\Printer\\Printer' => __DIR__ . '/../..' . '/phpstan/phpdoc-parser/src/Printer/Printer.php', 'Matomo\\Dependencies\\McpServer\\Psr\\Clock\\ClockInterface' => __DIR__ . '/../..' . '/psr/clock/src/ClockInterface.php', + 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Client\\ClientExceptionInterface' => __DIR__ . '/../..' . '/psr/http-client/src/ClientExceptionInterface.php', + 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Client\\ClientInterface' => __DIR__ . '/../..' . '/psr/http-client/src/ClientInterface.php', + 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Client\\NetworkExceptionInterface' => __DIR__ . '/../..' . '/psr/http-client/src/NetworkExceptionInterface.php', + 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Client\\RequestExceptionInterface' => __DIR__ . '/../..' . '/psr/http-client/src/RequestExceptionInterface.php', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\MessageInterface' => __DIR__ . '/../..' . '/psr/http-message/src/MessageInterface.php', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\RequestFactoryInterface' => __DIR__ . '/../..' . '/psr/http-factory/src/RequestFactoryInterface.php', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\RequestInterface' => __DIR__ . '/../..' . '/psr/http-message/src/RequestInterface.php', @@ -554,29 +598,6 @@ class ComposerStaticInitca6eb2087c12f87e6297cb3c15f15c76 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Message\\UriInterface' => __DIR__ . '/../..' . '/psr/http-message/src/UriInterface.php', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Server\\MiddlewareInterface' => __DIR__ . '/../..' . '/psr/http-server-middleware/src/MiddlewareInterface.php', 'Matomo\\Dependencies\\McpServer\\Psr\\Http\\Server\\RequestHandlerInterface' => __DIR__ . '/../..' . '/psr/http-server-handler/src/RequestHandlerInterface.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Comparator\\Comparator' => __DIR__ . '/../..' . '/symfony/finder/Comparator/Comparator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Comparator\\DateComparator' => __DIR__ . '/../..' . '/symfony/finder/Comparator/DateComparator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Comparator\\NumberComparator' => __DIR__ . '/../..' . '/symfony/finder/Comparator/NumberComparator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Exception\\AccessDeniedException' => __DIR__ . '/../..' . '/symfony/finder/Exception/AccessDeniedException.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Exception\\DirectoryNotFoundException' => __DIR__ . '/../..' . '/symfony/finder/Exception/DirectoryNotFoundException.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Finder' => __DIR__ . '/../..' . '/symfony/finder/Finder.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Gitignore' => __DIR__ . '/../..' . '/symfony/finder/Gitignore.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Glob' => __DIR__ . '/../..' . '/symfony/finder/Glob.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\CustomFilterIterator' => __DIR__ . '/../..' . '/symfony/finder/Iterator/CustomFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\DateRangeFilterIterator' => __DIR__ . '/../..' . '/symfony/finder/Iterator/DateRangeFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\DepthRangeFilterIterator' => __DIR__ . '/../..' . '/symfony/finder/Iterator/DepthRangeFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\ExcludeDirectoryFilterIterator' => __DIR__ . '/../..' . '/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\FileTypeFilterIterator' => __DIR__ . '/../..' . '/symfony/finder/Iterator/FileTypeFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\FilecontentFilterIterator' => __DIR__ . '/../..' . '/symfony/finder/Iterator/FilecontentFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\FilenameFilterIterator' => __DIR__ . '/../..' . '/symfony/finder/Iterator/FilenameFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\LazyIterator' => __DIR__ . '/../..' . '/symfony/finder/Iterator/LazyIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\MultiplePcreFilterIterator' => __DIR__ . '/../..' . '/symfony/finder/Iterator/MultiplePcreFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\PathFilterIterator' => __DIR__ . '/../..' . '/symfony/finder/Iterator/PathFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\RecursiveDirectoryIterator' => __DIR__ . '/../..' . '/symfony/finder/Iterator/RecursiveDirectoryIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\SizeRangeFilterIterator' => __DIR__ . '/../..' . '/symfony/finder/Iterator/SizeRangeFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\SortableIterator' => __DIR__ . '/../..' . '/symfony/finder/Iterator/SortableIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\Iterator\\VcsIgnoredFilterIterator' => __DIR__ . '/../..' . '/symfony/finder/Iterator/VcsIgnoredFilterIterator.php', - 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Finder\\SplFileInfo' => __DIR__ . '/../..' . '/symfony/finder/SplFileInfo.php', 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Uid\\AbstractUid' => __DIR__ . '/../..' . '/symfony/uid/AbstractUid.php', 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Uid\\BinaryUtil' => __DIR__ . '/../..' . '/symfony/uid/BinaryUtil.php', 'Matomo\\Dependencies\\McpServer\\Symfony\\Component\\Uid\\Command\\GenerateUlidCommand' => __DIR__ . '/../..' . '/symfony/uid/Command/GenerateUlidCommand.php', @@ -628,16 +649,16 @@ class ComposerStaticInitca6eb2087c12f87e6297cb3c15f15c76 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ImplementsFactory' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ImplementsFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\MethodFactory' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MethodFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\MethodParameterFactory' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MethodParameterFactory.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\MixinFactory' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/MixinFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PHPStanFactory' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PHPStanFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ParamFactory' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ParamFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PropertyFactory' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PropertyFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PropertyReadFactory' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PropertyReadFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\PropertyWriteFactory' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/PropertyWriteFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ReturnFactory' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ReturnFactory.php', - 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\StaticMethod' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php', - 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\TemplateExtendsFactory' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateExtendsFactory.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\TemplateCovariantFactory' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateCovariantFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\TemplateFactory' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateFactory.php', - 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\TemplateImplementsFactory' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/TemplateImplementsFactory.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\ThrowsFactory' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/ThrowsFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\VarFactory' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/VarFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\AlignFormatter' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php', @@ -670,7 +691,10 @@ class ComposerStaticInitca6eb2087c12f87e6297cb3c15f15c76 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Var_' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Version' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Element' => __DIR__ . '/../..' . '/phpdocumentor/reflection-common/src/Element.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Exception\\CannotCreateTag' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/Exception/CannotCreateTag.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Exception\\ParserException' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/Exception/ParserException.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Exception\\PcreException' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/Exception/PcreException.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Exception\\ReflectionDocblockException' => __DIR__ . '/../..' . '/phpdocumentor/reflection-docblock/src/Exception/ReflectionDocblockException.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\File' => __DIR__ . '/../..' . '/phpdocumentor/reflection-common/src/File.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Fqsen' => __DIR__ . '/../..' . '/phpdocumentor/reflection-common/src/Fqsen.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\FqsenResolver' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/FqsenResolver.php', @@ -678,19 +702,26 @@ class ComposerStaticInitca6eb2087c12f87e6297cb3c15f15c76 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Project' => __DIR__ . '/../..' . '/phpdocumentor/reflection-common/src/Project.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\ProjectFactory' => __DIR__ . '/../..' . '/phpdocumentor/reflection-common/src/ProjectFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoType' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoType.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ArrayKey' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/ArrayKey.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ArrayShape' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/ArrayShape.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ArrayShapeItem' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/ArrayShapeItem.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\CallableArray' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/CallableArray.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\CallableString' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/CallableString.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ClassString' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/ClassString.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ClosedResource' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/ClosedResource.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\Conditional' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/Conditional.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ConditionalForParameter' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/ConditionalForParameter.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ConstExpression' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/ConstExpression.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\EnumString' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/EnumString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\False_' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/False_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\FloatValue' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/FloatValue.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\Generic' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/Generic.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\HtmlEscapedString' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/HtmlEscapedString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\IntMask' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/IntMask.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\IntMaskOf' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/IntMaskOf.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\IntegerRange' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/IntegerRange.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\IntegerValue' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/IntegerValue.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\InterfaceString' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/InterfaceString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\KeyOf' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/KeyOf.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ListShape' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/ListShape.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ListShapeItem' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/ListShapeItem.php', @@ -698,39 +729,49 @@ class ComposerStaticInitca6eb2087c12f87e6297cb3c15f15c76 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\LiteralString' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/LiteralString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\LowercaseString' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/LowercaseString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NegativeInteger' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/NegativeInteger.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NeverReturn' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/NeverReturn.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NeverReturns' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/NeverReturns.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NoReturn' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/NoReturn.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NonEmptyArray' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyArray.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NonEmptyList' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyList.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NonEmptyLowercaseString' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyLowercaseString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NonEmptyString' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyString.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NonFalsyString' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/NonFalsyString.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NonNegativeInteger' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/NonNegativeInteger.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NonPositiveInteger' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/NonPositiveInteger.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NonZeroInteger' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/NonZeroInteger.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\NumericString' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/NumericString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\Numeric_' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/Numeric_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ObjectShape' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/ObjectShape.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ObjectShapeItem' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/ObjectShapeItem.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\OffsetAccess' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/OffsetAccess.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\OpenResource' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/OpenResource.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\PositiveInteger' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/PositiveInteger.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\PrivatePropertiesOf' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/PrivatePropertiesOf.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\PropertiesOf' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/PropertiesOf.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ProtectedPropertiesOf' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/ProtectedPropertiesOf.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\PublicPropertiesOf' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/PublicPropertiesOf.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\Scalar' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/Scalar.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ShapeItem' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/ShapeItem.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\StringValue' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/StringValue.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\TraitString' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/TraitString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\True_' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/True_.php', + 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\TruthyString' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/TruthyString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\PseudoTypes\\ValueOf' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/PseudoTypes/ValueOf.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Type' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Type.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\TypeResolver' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/TypeResolver.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\AbstractList' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/AbstractList.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\AggregatedType' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/AggregatedType.php', - 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\ArrayKey' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/ArrayKey.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Array_' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/Array_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Boolean' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/Boolean.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\CallableParameter' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/CallableParameter.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Callable_' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/Callable_.php', - 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\ClassString' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/ClassString.php', - 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Collection' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/Collection.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Compound' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/Compound.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Context' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/Context.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\ContextFactory' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/ContextFactory.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Expression' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/Expression.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Float_' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/Float_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Integer' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/Integer.php', - 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\InterfaceString' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/InterfaceString.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Intersection' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/Intersection.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Iterable_' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/Iterable_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Mixed_' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/Mixed_.php', @@ -740,7 +781,6 @@ class ComposerStaticInitca6eb2087c12f87e6297cb3c15f15c76 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Object_' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/Object_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Parent_' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/Parent_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Resource_' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/Resource_.php', - 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Scalar' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/Scalar.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Self_' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/Self_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\Static_' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/Static_.php', 'Matomo\\Dependencies\\McpServer\\phpDocumentor\\Reflection\\Types\\String_' => __DIR__ . '/../..' . '/phpdocumentor/type-resolver/src/Types/String_.php', @@ -752,7 +792,7 @@ class ComposerStaticInitca6eb2087c12f87e6297cb3c15f15c76 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->classMap = ComposerStaticInitca6eb2087c12f87e6297cb3c15f15c76::$classMap; + $loader->classMap = ComposerStaticInit8b3681e24fa67a5543f8921436dddf2a::$classMap; }, null, ClassLoader::class); }