diff options
Diffstat (limited to 'vendor/gipfl/openrpc/src')
28 files changed, 1610 insertions, 0 deletions
diff --git a/vendor/gipfl/openrpc/src/Components.php b/vendor/gipfl/openrpc/src/Components.php new file mode 100644 index 0000000..621a9a0 --- /dev/null +++ b/vendor/gipfl/openrpc/src/Components.php @@ -0,0 +1,68 @@ +<?php + +namespace gipfl\OpenRpc; + +use JsonSerializable; + +/** + * Holds a set of reusable objects for different aspects of the OpenRPC. All + * objects defined within the components object will have no effect on the API + * unless they are explicitly referenced from properties outside the components + * object. + * + * All the fixed fields declared are objects that MUST use keys that match the + * regular expression: ^[a-zA-Z0-9\.\-_]+$ + */ +class Components implements JsonSerializable +{ + use SimpleJsonSerializer; + + /** + * An object to hold reusable Content Descriptor Objects + * + * @var ContentDescriptor[] Map[string, Content Descriptor Object] + */ + public $contentDescriptors; + + /** + * An object to hold reusable Schema Objects + * + * @var SchemaObject[] Map[string, Schema Object] + */ + public $schemas; + + /** + * An object to hold reusable Example Objects + * + * @var Example[] Map[string, Example Object] + */ + public $examples; + + /** + * An object to hold reusable Link Objects + * + * @var Link[] Map[string, Link Object] + */ + public $links; + + /** + * An object to hold reusable Error Objects + * + * @var Error[] Map[string, Error Object] + */ + public $errors; + + /** + * An object to hold reusable Example Pairing Objects + * + * @var ExamplePairing[] Map[string, Example Pairing Object] + */ + public $examplePairingObjects; + + /** + * An object to hold reusable Tag Objects + * + * @var TagObject[] Map[string, Tag Object] + */ + public $tags; +} diff --git a/vendor/gipfl/openrpc/src/Contact.php b/vendor/gipfl/openrpc/src/Contact.php new file mode 100644 index 0000000..e957719 --- /dev/null +++ b/vendor/gipfl/openrpc/src/Contact.php @@ -0,0 +1,49 @@ +<?php + +namespace gipfl\OpenRpc; + +use JsonSerializable; + +/** + * Contact information for the exposed API + */ +class Contact implements JsonSerializable +{ + use SimpleJsonSerializer; + + /** + * The identifying name of the contact person/organization + * + * @var string|null + */ + public $name; + + /** + * The URL pointing to the contact information. MUST be in the format of a + * URL. + * + * @var string|null + */ + public $url; + + /** + * The email address of the contact person/organization. MUST be in the + * format of an email address. + * + * @var string|null + */ + public $email; + + /** + * Contact constructor. + * @param string|null $name + * @param string|null $url + * @param string|null $email + */ + public function __construct($name = null, $url = null, $email = null) + { + $this->name = $name; + $this->url = $url; + $this->email = $email; + } +} diff --git a/vendor/gipfl/openrpc/src/ContentDescriptor.php b/vendor/gipfl/openrpc/src/ContentDescriptor.php new file mode 100644 index 0000000..42772fb --- /dev/null +++ b/vendor/gipfl/openrpc/src/ContentDescriptor.php @@ -0,0 +1,73 @@ +<?php + +namespace gipfl\OpenRpc; + +use JsonSerializable; + +/** + * Content Descriptors are objects that do just as they suggest - describe + * content. They are reusable ways of describing either parameters or result. + * They MUST have a schema. + */ +class ContentDescriptor implements JsonSerializable +{ + use SimpleJsonSerializer; + + /** + * REQUIRED. Name of the content that is being described. If the content + * described is a method parameter assignable by-name, this field SHALL + * define the parameter’s key (ie name). + * + * @var string + */ + public $name; + + /** + * A short summary of the content that is being described. + * + * @var string|null + */ + public $summary; + + /** + * A verbose explanation of the content descriptor behavior. GitHub Flavored + * Markdown syntax MAY be used for rich text representation. + * + * @var string|null + */ + public $description; + + /** + * Determines if the content is a required field. Default value is false. + * + * @var boolean|null + */ + public $required; + + /** + * REQUIRED. Schema that describes the content. + * + * The Schema Object allows the definition of input and output data types. + * The Schema Objects MUST follow the specifications outline in the JSON + * Schema Specification 7 Alternatively, any time a Schema Object can be + * used, a Reference Object can be used in its place. This allows referencing + * definitions instead of defining them inline. + * + * @var SchemaObject + */ + public $schema; + + /** + * Specifies that the content is deprecated and SHOULD be transitioned out + * of usage. Default value is false. + * + * @var boolean|null + */ + public $deprecated; + + public function __construct($name, $schema) + { + $this->name = $name; + $this->schema = $schema; + } +} diff --git a/vendor/gipfl/openrpc/src/Error.php b/vendor/gipfl/openrpc/src/Error.php new file mode 100644 index 0000000..25ed818 --- /dev/null +++ b/vendor/gipfl/openrpc/src/Error.php @@ -0,0 +1,54 @@ +<?php + +namespace gipfl\OpenRpc; + +use JsonSerializable; + +/** + * Defines an application level error. + */ +class Error implements JsonSerializable +{ + use SimpleJsonSerializer; + + /** + * Application Defined Error Code + * + * REQUIRED. A Number that indicates the error type that occurred. This + * MUST be an integer. The error codes from and including -32768 to -32000 + * are reserved for pre-defined errors. These pre-defined errors SHOULD be + * assumed to be returned from any JSON-RPC api. + * + * @var int + */ + public $code; + + /** + * REQUIRED. A String providing a short description of the error. The + * message SHOULD be limited to a concise single sentence. + * + * @var string + */ + public $message; + + /** + * A Primitive or Structured value that contains additional information + * about the error. This may be omitted. The value of this member is defined + * by the Server (e.g. detailed error information, nested errors etc.). + * + * @var mixed + */ + public $data; + + /** + * @param int $code + * @param string $message + * @param mixed|null $data + */ + public function __construct($code, $message, $data = null) + { + $this->code = $code; + $this->message = $message; + $this->data = $data; + } +} diff --git a/vendor/gipfl/openrpc/src/Example.php b/vendor/gipfl/openrpc/src/Example.php new file mode 100644 index 0000000..1e5aefe --- /dev/null +++ b/vendor/gipfl/openrpc/src/Example.php @@ -0,0 +1,36 @@ +<?php + +namespace gipfl\OpenRpc; + +use JsonSerializable; + +/** + * The Example object is an object the defines an example that is intended to + * match a given Content Descriptor Schema. If the Content Descriptor Schema + * includes examples, the value from this Example Object supersedes the value + * of the schema example. + * + * In all cases, the example vaJsonSerializablelue is expected to be compatible with the type + * schema of its associated value. Tooling implementations MAY choose to + * validate compatibility automatically, and reject the example value(s) if + * incompatible. + */ +class Example implements JsonSerializable +{ + use SimpleJsonSerializer; + + /** @var string|null Name for the example pairing */ + public $name; + + /** @var string|null A verbose explanation of the example pairing */ + public $summary; + + /** @var string|null Short description for the example pairing */ + public $description; + + /** @var <Example|Reference>[] Example parameters */ + public $params; + + /** @var Example|Reference Example result */ + public $result; +} diff --git a/vendor/gipfl/openrpc/src/ExamplePairing.php b/vendor/gipfl/openrpc/src/ExamplePairing.php new file mode 100644 index 0000000..6f34137 --- /dev/null +++ b/vendor/gipfl/openrpc/src/ExamplePairing.php @@ -0,0 +1,30 @@ +<?php + +namespace gipfl\OpenRpc; + +use JsonSerializable; + +/** + * The example Pairing object consists of a set of example params and result. + * The result is what you can expect from the JSON-RPC service given the exact + * params. + */ +class ExamplePairing implements JsonSerializable +{ + use SimpleJsonSerializer; + + /** @var string|null Name for the example pairing */ + public $name; + + /** @var string|null A verbose explanation of the example pairing */ + public $summary; + + /** @var string|null Short description for the example pairing */ + public $description; + + /** @var <Example|Reference>[] Example parameters */ + public $params; + + /** @var Example|Reference Example result */ + public $result; +} diff --git a/vendor/gipfl/openrpc/src/ExternalDocumentation.php b/vendor/gipfl/openrpc/src/ExternalDocumentation.php new file mode 100644 index 0000000..54b5883 --- /dev/null +++ b/vendor/gipfl/openrpc/src/ExternalDocumentation.php @@ -0,0 +1,37 @@ +<?php + +namespace gipfl\OpenRpc; + +use JsonSerializable; + +/** + * Allows referencing an external resource for extended documentation + */ +class ExternalDocumentation implements JsonSerializable +{ + use SimpleJsonSerializer; + + /** + * REQUIRED. The URL for the target documentation. Value MUST be in the + * format of a URL. + * + * @var string + */ + public $url; + + /** + * A verbose explanation of the target documentation. GitHub Flavored Markdown + * syntax MAY be used for rich text representation. + * + * @var string|null + */ + public $description; + + /** + * @param $url + */ + public function __construct($url) + { + $this->url = $url; + } +} diff --git a/vendor/gipfl/openrpc/src/Info.php b/vendor/gipfl/openrpc/src/Info.php new file mode 100644 index 0000000..3c957c9 --- /dev/null +++ b/vendor/gipfl/openrpc/src/Info.php @@ -0,0 +1,69 @@ +<?php + +namespace gipfl\OpenRpc; + +use JsonSerializable; + +/** + * The object provides metadata about the API. The metadata MAY be used by the + * clients if needed, and MAY be presented in editing or documentation + * generation tools for convenience. + */ +class Info implements JsonSerializable +{ + use SimpleJsonSerializer; + + /** + * REQUIRED. The title of the application + * + * @var string + */ + public $title; + /** + * A verbose description of the application. GitHub Flavored Markdown syntax + * MAY be used for rich text representation. + * + * @var string|null + */ + public $description; + + /** + * A URL to the Terms of Service for the API. MUST be in the format of a URL + * + * @var string|null + */ + public $termsOfService; + + /** + * The contact information for the exposed API + * + * @var Contact|null + */ + public $contact; + + /** + * The license information for the exposed API + * + * @var License|null + */ + public $license; + + /** + * REQUIRED. The version of the OpenRPC document (which is distinct from the + * OpenRPC Specification version or the API implementation version) + * + * @var string + */ + public $version; + + /** + * Info constructor. + * @param string $title + * @param string $version + */ + public function __construct($title, $version) + { + $this->title = $title; + $this->version = $version; + } +} diff --git a/vendor/gipfl/openrpc/src/License.php b/vendor/gipfl/openrpc/src/License.php new file mode 100644 index 0000000..3bb8904 --- /dev/null +++ b/vendor/gipfl/openrpc/src/License.php @@ -0,0 +1,37 @@ +<?php + +namespace gipfl\OpenRpc; + +use JsonSerializable; + +/** + * License information for the exposed API. + */ +class License implements JsonSerializable +{ + use SimpleJsonSerializer; + + /** + * REQUIRED. The license name used for the API. + * + * @var string + */ + public $name; + + /** + * A URL to the license used for the API. MUST be in the format of a URL. + * + * @var string|null + */ + public $url; + + /** + * @param string $name + * @param string|null $url + */ + public function __construct($name, $url = null) + { + $this->name = $name; + $this->url = $url; + } +} diff --git a/vendor/gipfl/openrpc/src/Link.php b/vendor/gipfl/openrpc/src/Link.php new file mode 100644 index 0000000..d0ac517 --- /dev/null +++ b/vendor/gipfl/openrpc/src/Link.php @@ -0,0 +1,91 @@ +<?php + +namespace gipfl\OpenRpc; + +use JsonSerializable; + +/** + * The Link object represents a possible design-time link for a result. The + * presence of a link does not guarantee the caller’s ability to successfully + * invoke it, rather it provides a known relationship and traversal mechanism + * between results and other methods. + * + * Unlike dynamic links (i.e. links provided in the result payload), the OpenRPC + * linking mechanism does not require link information in the runtime result. + * + * For computing links, and providing instructions to execute them, a runtime + * expression is used for accessing values in an method and using them as + * parameters while invoking the linked method. + */ +class Link implements JsonSerializable +{ + use SimpleJsonSerializer; + + /** + * REQUIRED. Canonical name of the link. + * + * @var string + */ + public $name; + + /** + * Short description for the link. + * + * @var string|null + */ + public $summary; + + /** + * A description of the link. GitHub Flavored Markdown syntax MAY be used + * for rich text representation. + * + * @var string|null + */ + public $description; + + /** + * The name of an existing, resolvable OpenRPC method, as defined with a + * unique method. This field MUST resolve to a unique Method Object. As + * opposed to Open Api, Relative method values ARE NOT permitted. + * + * @var string|null + */ + public $method; + + /** + * A map representing parameters to pass to a method as specified with + * method. The key is the parameter name to be used, whereas the value can + * be a constant or a runtime expression to be evaluated and passed to the + * linked method. + * + * A linked method must be identified directly, and must exist in the list + * of methods defined by the Methods Object. + * + * When a runtime expression fails to evaluate, no parameter value is passed + * to the target method. + * + * Values from the result can be used to drive a linked method. + * + * Clients follow all links at their discretion. Neither permissions, nor + * the capability to make a successful call to that link, is guaranteed + * solely by the existence of a relationship. + * + * @var array Map[string, Any | RuntimeExpression] + */ + public $params; + + /** + * A server object to be used by the target method. + * + * @var Server|null + */ + public $server; + + /** + * @param string $name + */ + public function __construct($name) + { + $this->name = $name; + } +} diff --git a/vendor/gipfl/openrpc/src/Method.php b/vendor/gipfl/openrpc/src/Method.php new file mode 100644 index 0000000..54226e3 --- /dev/null +++ b/vendor/gipfl/openrpc/src/Method.php @@ -0,0 +1,133 @@ +<?php + +namespace gipfl\OpenRpc; + +use JsonSerializable; + +/** + * Describes the interface for the given method name. The method name is used + * as the method field of the JSON-RPC body. It therefore MUST be unique. + */ +class Method implements JsonSerializable +{ + use SimpleJsonSerializer; + + /** + * REQUIRED. The cannonical name for the method. The name MUST be unique + * within the methods array. + * + * @var string + */ + public $name; + + /** + * A list of tags for API documentation control. Tags can be used for + * logical grouping of methods by resources or any other qualifier. + * + * @var TagObject[]|Reference[] + */ + public $tags; + + /** + * A short summary of what the method does + * + * @var string|null + */ + public $summary; + + /** + * A verbose explanation of the method behavior. GitHub Flavored Markdown + * syntax MAY be used for rich text representation. + * + * @var string|null + */ + public $description; + + /** + * Additional external documentation for this method + * + * @var ExternalDocumentation + */ + public $externalDocs; + + /** + * REQUIRED. A list of parameters that are applicable for this method. The + * list MUST NOT include duplicated parameters and therefore require name + * to be unique. The list can use the Reference Object to link to parameters + * that are defined by the Content Descriptor Object. All optional params + * (content descriptor objects with “required”: false) MUST be positioned + * after all required params in the list. + * + * @var <ContentDescriptor|Reference>[] + */ + public $params; + + /** + * REQUIRED. The description of the result returned by the method. It MUST + * be a Content Descriptor. + * + * @var ContentDescriptor|Reference + */ + public $result; + + /** + * Declares this method to be deprecated. Consumers SHOULD refrain from + * usage of the declared method. Default value is false. + * + * @var boolean + */ + public $deprecated; + + /** + * An alternative servers array to service this method. If an alternative + * servers array is specified at the Root level, it will be overridden by + * this value. + * + * @var Server[] + */ + public $servers; + + /** + * A list of custom application defined errors that MAY be returned. The + * Errors MUST have unique error codes. + * + * @var <Error|Reference>[] + */ + public $errors; + + /** + * A list of possible links from this method call + * + * @var <Link|Reference>[] + */ + public $links; + + /** + * The expected format of the parameters. As per the JSON-RPC 2.0 specification, + * the params of a JSON-RPC request object may be an array, object, or either + * (represented as by-position, by-name, and either respectively). When a method + * has a paramStructure value of by-name, callers of the method MUST send a + * JSON-RPC request object whose params field is an object. Further, the key + * names of the params object MUST be the same as the contentDescriptor.names + * for the given method. Defaults to "either". + * + * @var string "by-name" | "by-position" | "either" + */ + public $paramStructure; + + /** + * Array of Example Pairing Object where each example includes a valid + * params-to-result Content Descriptor pairing. + * + * @var ExamplePairing [] + */ + public $examples; + + /** + * @param $name + */ + public function __construct($name) + { + $this->name = $name; + } +} diff --git a/vendor/gipfl/openrpc/src/OpenRpcDocument.php b/vendor/gipfl/openrpc/src/OpenRpcDocument.php new file mode 100644 index 0000000..62be245 --- /dev/null +++ b/vendor/gipfl/openrpc/src/OpenRpcDocument.php @@ -0,0 +1,75 @@ +<?php + +namespace gipfl\OpenRpc; + +use JsonSerializable; + +/** + * This is the root object of the OpenRPC document. The contents of this object + * represent a whole OpenRPC document. How this object is constructed or stored + * is outside the scope of the OpenRPC Specification. + */ +class OpenRpcDocument implements JsonSerializable +{ + use SimpleJsonSerializer; + + /** + * REQUIRED. This string MUST be the semantic version number of the OpenRPC + * Specification version that the OpenRPC document uses. The openrpc field + * SHOULD be used by tooling specifications and clients to interpret the + * OpenRPC document. This is not related to the API info.version string. + * + * @var string + */ + public $openrpc; + + /** + * REQUIRED. Provides metadata about the API. The metadata MAY be used by + * tooling as required. + * + * @var Info + */ + public $info; + + /** + * An array of Server Objects, which provide connectivity information to a + * target server. If the servers property is not provided, or is an empty + * array, the default value would be a Server Object with a url value of + * localhost. + * + * @var Server[]|null + */ + public $servers; + + /** + * REQUIRED. The available methods for the API. While it is required, the + * array may be empty (to handle security filtering, for example). + * + * @var Method[]|Reference[] + */ + public $methods = []; + + /** + * An element to hold various schemas for the specification + * + * @var Components|null + */ + public $components; + + /** + * Additional external documentation + * + * @var ExternalDocumentation|null + */ + public $externalDocs; + + /** + * @param string $openRpcVersion + * @param Info $info + */ + public function __construct($openRpcVersion, Info $info) + { + $this->openrpc = $openRpcVersion; + $this->info = $info; + } +} diff --git a/vendor/gipfl/openrpc/src/Reference.php b/vendor/gipfl/openrpc/src/Reference.php new file mode 100644 index 0000000..e954293 --- /dev/null +++ b/vendor/gipfl/openrpc/src/Reference.php @@ -0,0 +1,32 @@ +<?php + +namespace gipfl\OpenRpc; + +use JsonSerializable; + +/** + * A simple object to allow referencing other components in the specification, + * internally and externally. + * + * The Reference Object is defined by JSON Schema and follows the same structure, + * behavior and rules. + */ +class Reference implements JsonSerializable +{ + /** @var string REQUIRED. The reference string */ + public $ref; + + /** + * @param string $ref + */ + public function __construct($ref) + { + $this->ref = $ref; + } + + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return (object) ['$ref' => $this->ref]; + } +} diff --git a/vendor/gipfl/openrpc/src/Reflection/MetaDataClass.php b/vendor/gipfl/openrpc/src/Reflection/MetaDataClass.php new file mode 100644 index 0000000..4e9427e --- /dev/null +++ b/vendor/gipfl/openrpc/src/Reflection/MetaDataClass.php @@ -0,0 +1,76 @@ +<?php + +namespace gipfl\OpenRpc\Reflection; + +use InvalidArgumentException; +use ReflectionClass; +use ReflectionException; +use function lcfirst; +use function preg_match; + +class MetaDataClass +{ + /** @var MetaDataMethod[] */ + public $methods = []; + + /** @var string|null */ + public $error; + + /** + * @param string $class + * @throws ReflectionException + * @return static + */ + public static function analyze($class) + { + $info = new static(); + + $ref = new ReflectionClass($class); + + foreach ($ref->getMethods() as $method) { + $methodName = $method->getName(); + if (! preg_match('/^(.+)(Request|Notification)$/', $methodName, $match)) { + continue; + } + + $info->addMethod(MethodCommentParser::parseMethod( + $match[1], + lcfirst($match[2]), + $method->getDocComment() + )); + } + + return $info; + } + + public function addMethod(MetaDataMethod $method) + { + $name = $method->name; + if (isset($this->methods[$name])) { + throw new InvalidArgumentException("Cannot add method '$name' twice"); + } + + $this->methods[$name] = $method; + } + + /** + * @return MetaDataMethod[] + */ + public function getMethods() + { + return $this->methods; + } + + /** + * @param $name + * @return MetaDataMethod + */ + public function getMethod($name) + { + if (isset($this->methods[$name])) { + return $this->methods[$name]; + } + + throw new InvalidArgumentException("There is no '$name' method"); + } +} diff --git a/vendor/gipfl/openrpc/src/Reflection/MetaDataMethod.php b/vendor/gipfl/openrpc/src/Reflection/MetaDataMethod.php new file mode 100644 index 0000000..e711e6e --- /dev/null +++ b/vendor/gipfl/openrpc/src/Reflection/MetaDataMethod.php @@ -0,0 +1,111 @@ +<?php + +namespace gipfl\OpenRpc\Reflection; + +use InvalidArgumentException; + +class MetaDataMethod +{ + /** @var string */ + public $name; + + /** @var string Either 'request' or 'notification' */ + public $requestType; + + /** @var string */ + public $resultType; + + /** @var MetaDataParameter[] */ + public $parameters = []; + + /** @var string */ + public $title; + + /** @var string */ + public $description; + + public function __construct($name, $requestType) + { + $this->name = $name; + $this->requestType = $requestType; + } + + public function addParsed(MethodCommentParser $parser) + { + $this->resultType = $parser->getResultType(); + $this->parameters = $parser->getParams(); + $this->title = $parser->getTitle(); + $this->description = $parser->getDescription(); + + return $this; + } + + /** + * @param MetaDataParameter $parameter + */ + public function addParameter(MetaDataParameter $parameter) + { + $this->parameters[$parameter->getName()] = $parameter; + } + + /** + * @param $name + * @return MetaDataParameter + */ + public function getParameter($name) + { + if (isset($this->parameters[$name])) { + return $this->parameters[$name]; + } + + throw new InvalidArgumentException("There is no '$name' parameter" . print_r($this->parameters, 1)); + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @return string + */ + public function getRequestType() + { + return $this->requestType; + } + + /** + * @return string + */ + public function getResultType() + { + return $this->resultType ?: 'void'; + } + + /** + * @return MetaDataParameter[] + */ + public function getParameters() + { + return $this->parameters; + } + + /** + * @return string + */ + public function getTitle() + { + return $this->title; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } +} diff --git a/vendor/gipfl/openrpc/src/Reflection/MetaDataParameter.php b/vendor/gipfl/openrpc/src/Reflection/MetaDataParameter.php new file mode 100644 index 0000000..7ed76dd --- /dev/null +++ b/vendor/gipfl/openrpc/src/Reflection/MetaDataParameter.php @@ -0,0 +1,46 @@ +<?php + +namespace gipfl\OpenRpc\Reflection; + +class MetaDataParameter +{ + /** @var string */ + public $name; + + /** @var string */ + public $type; + + /** @var string */ + public $description; + + public function __construct($name, $type, $description = null) + { + $this->name = $name; + $this->type = $type; + $this->description = $description; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } +} diff --git a/vendor/gipfl/openrpc/src/Reflection/MetaDataTagParser.php b/vendor/gipfl/openrpc/src/Reflection/MetaDataTagParser.php new file mode 100644 index 0000000..d1df585 --- /dev/null +++ b/vendor/gipfl/openrpc/src/Reflection/MetaDataTagParser.php @@ -0,0 +1,60 @@ +<?php + +namespace gipfl\OpenRpc\Reflection; + +class MetaDataTagParser +{ + const DEFAULT_TAG_TYPE = Tag::class; + + const SPECIAL_TAGS = [ + 'param' => ParamTag::class, + 'throws' => ThrowsTag::class, + 'return' => ReturnTag::class, + ]; + + protected $tagType; + + protected $string; + + public function __construct($tagType, $string) + { + $this->tagType = $tagType; + $this->string = $string; + } + + public function getTag() + { + $type = $this->getTagType(); + $tags = static::SPECIAL_TAGS; + if (isset($tags[$type])) { + $class = self::SPECIAL_TAGS[$type]; + } else { + $class = self::DEFAULT_TAG_TYPE; + } + + return new $class($type, $this->getString()); + } + + /** + * @return string + */ + public function getTagType() + { + return $this->tagType; + } + + /** + * @return string + */ + public function getString() + { + return $this->string; + } + + public function appendValueString($string) + { + $this->string .= $string; + + return $this; + } +} diff --git a/vendor/gipfl/openrpc/src/Reflection/MetaDataTagSet.php b/vendor/gipfl/openrpc/src/Reflection/MetaDataTagSet.php new file mode 100644 index 0000000..a246fcb --- /dev/null +++ b/vendor/gipfl/openrpc/src/Reflection/MetaDataTagSet.php @@ -0,0 +1,69 @@ +<?php + +namespace gipfl\OpenRpc\Reflection; + +class MetaDataTagSet +{ + /** @var Tag[] */ + protected $tags; + + public function __construct() + { + $this->tags = []; + } + + public function add(Tag $tag) + { + $this->tags[] = $tag; + } + + /** + * @param string $type + * @return static + */ + public function byType($type) + { + $set = new static(); + foreach ($this->tags as $tag) { + if ($tag->tagType === $type) { + $set->add($tag); + } + } + + return $set; + } + + /** + * @return MetaDataParameter[] + */ + public function getParams() + { + $result = []; + foreach ($this->byType('param')->getTags() as $tag) { + assert($tag instanceof ParamTag); + $result[] = new MetaDataParameter($tag->name, $tag->dataType, $tag->description); + // TODO: variadic! + } + + return $result; + } + + /** + * @return string|null + */ + public function getReturnType() + { + foreach ($this->byType('return')->getTags() as $tag) { + assert($tag instanceof ReturnTag); + // TODO: return a class, we need the description + return $tag->dataType; + } + + return null; + } + + public function getTags() + { + return $this->tags; + } +} diff --git a/vendor/gipfl/openrpc/src/Reflection/MethodCommentParser.php b/vendor/gipfl/openrpc/src/Reflection/MethodCommentParser.php new file mode 100644 index 0000000..6f20f93 --- /dev/null +++ b/vendor/gipfl/openrpc/src/Reflection/MethodCommentParser.php @@ -0,0 +1,163 @@ +<?php + +namespace gipfl\OpenRpc\Reflection; + +use function explode; +use function implode; +use function preg_match; +use function preg_replace; +use function substr; +use function trim; + +class MethodCommentParser +{ + const REGEXP_START_OF_COMMENT = '~^\s*/\*\*\n~s'; + const REGEXP_COMMENT_LINE_START = '~^\s*\*\s?~'; + const REGEXP_END_OF_COMMENT = '~\n\s*\*/\s*~s'; + const REGEXP_TAG_TYPE_VALUE = '/^@([A-z0-9]+)\s+(.+?)$/'; + + protected $paragraphs = []; + protected $currentParagraph; + + /** @var MetaDataMethod */ + protected $meta; + + /** @var MetaDataTagParser|null */ + protected $currentTag; + + /** @var MetaDataTagSet */ + protected $tags; + + protected function __construct(MetaDataMethod $meta) + { + $this->meta = $meta; + $this->tags = new MetaDataTagSet(); + } + + public function getTitle() + { + return $this->meta->title; + } + + public function getParams() + { + return $this->getTags()->getParams(); + } + + public function getResultType() + { + return $this->getTags()->getReturnType(); + } + + public function getDescription() + { + return implode("\n", $this->paragraphs); + } + + public function getTags() + { + return $this->tags; + } + + protected function parseLine($line) + { + // Strip * at line start + $line = preg_replace(self::REGEXP_COMMENT_LINE_START, '', $line); + $line = trim($line); + if (preg_match(self::REGEXP_TAG_TYPE_VALUE, $line, $match)) { + $this->finishCurrentObjects(); + $this->currentTag = new MetaDataTagParser($match[1], $match[2]); + return; + } + + if ($this->currentTag) { + $this->currentTag->appendValueString($line); + return; + } + + $this->eventuallyFinishCurrentTag(); + $this->appendToParagraph($line); + } + + protected function appendToParagraph($line) + { + if (trim($line) === '') { + $this->eventuallyFinishCurrentLine(); + return; + } + + if ($this->currentParagraph === null) { + $this->currentParagraph = & $this->paragraphs[]; + $this->currentParagraph = $line; + } else { + if (substr($line, 0, 2) === ' ') { + $this->currentParagraph .= "\n" . $line; + } else { + $this->currentParagraph .= ' ' . $line; + } + } + } + + protected function finishCurrentObjects() + { + $this->eventuallyFinishCurrentTag(); + $this->eventuallyFinishCurrentLine(); + } + + protected function eventuallyFinishCurrentTag() + { + if ($this->currentTag) { + $this->tags->add($this->currentTag->getTag()); + $this->currentTag = null; + } + } + + protected function eventuallyFinishCurrentLine() + { + if ($this->currentParagraph !== null) { + unset($this->currentParagraph); + $this->currentParagraph = null; + } + } + + protected function parse($plain) + { + foreach (explode("\n", $plain) as $line) { + $this->parseLine($line); + } + $this->finishCurrentObjects(); + } + + public static function parseMethod($methodName, $methodType, $raw) + { + $meta = new MetaDataMethod($methodName, $methodType); + $self = new static($meta); + $plain = (string) $raw; + static::stripStartOfComment($plain); + static::stripEndOfComment($plain); + $self->parse($plain); + $meta->addParsed($self); + + return $meta; + } + + /** + * Removes comment start -> /** + * + * @param $string + */ + protected static function stripStartOfComment(&$string) + { + $string = preg_replace(self::REGEXP_START_OF_COMMENT, '', $string); + } + + /** + * Removes comment end -> * / + * + * @param $string + */ + protected static function stripEndOfComment(&$string) + { + $string = preg_replace(self::REGEXP_END_OF_COMMENT, "\n", $string); + } +} diff --git a/vendor/gipfl/openrpc/src/Reflection/ParamTag.php b/vendor/gipfl/openrpc/src/Reflection/ParamTag.php new file mode 100644 index 0000000..32a8b33 --- /dev/null +++ b/vendor/gipfl/openrpc/src/Reflection/ParamTag.php @@ -0,0 +1,41 @@ +<?php + +namespace gipfl\OpenRpc\Reflection; + +class ParamTag extends Tag +{ + public $name; + + public $dataType; + + public $description; + + public $isVariadic = false; + + protected function parseTagValue($value) + { + $parts = preg_split('/(\s+)/us', $value, 3, PREG_SPLIT_DELIM_CAPTURE); + if (substr($parts[0], 0, 1) !== '$' && substr($parts[0], 0, 4) !== '...$') { + $this->dataType = array_shift($parts); + array_shift($parts); + } + if (empty($parts)) { + return; + } + + if (substr($parts[0], 0, 1) === '$') { + $this->name = substr($parts[0], 1); + array_shift($parts); + array_shift($parts); + } elseif (substr($parts[0], 0, 4) !== '...$') { + $this->name = substr($parts[0], 4); + $this->isVariadic = true; + array_shift($parts); + array_shift($parts); + } + + if (! empty($parts)) { + $this->description = implode($parts); + } + } +} diff --git a/vendor/gipfl/openrpc/src/Reflection/ReturnTag.php b/vendor/gipfl/openrpc/src/Reflection/ReturnTag.php new file mode 100644 index 0000000..0a147cf --- /dev/null +++ b/vendor/gipfl/openrpc/src/Reflection/ReturnTag.php @@ -0,0 +1,7 @@ +<?php + +namespace gipfl\OpenRpc\Reflection; + +class ReturnTag extends TypeDescriptionTag +{ +} diff --git a/vendor/gipfl/openrpc/src/Reflection/Tag.php b/vendor/gipfl/openrpc/src/Reflection/Tag.php new file mode 100644 index 0000000..038cb53 --- /dev/null +++ b/vendor/gipfl/openrpc/src/Reflection/Tag.php @@ -0,0 +1,37 @@ +<?php + +namespace gipfl\OpenRpc\Reflection; + +class Tag +{ + /** @var string */ + public $tagType; + + /** @var string */ + public $tagValue; + + public function __construct($tagType, $tagValue) + { + $this->tagType = $tagType; + $this->setTagValue($tagValue); + $this->parseTagValue(trim($tagValue)); + } + + public function setTagValue($value) + { + $this->tagValue = $value; + + return $this; + } + + /** + * Parse Tag value into Tag-specific properties + * + * Override this method for specific tag types + * + * @param $tagValue + */ + protected function parseTagValue($tagValue) + { + } +} diff --git a/vendor/gipfl/openrpc/src/Reflection/ThrowsTag.php b/vendor/gipfl/openrpc/src/Reflection/ThrowsTag.php new file mode 100644 index 0000000..42d1fd6 --- /dev/null +++ b/vendor/gipfl/openrpc/src/Reflection/ThrowsTag.php @@ -0,0 +1,7 @@ +<?php + +namespace gipfl\OpenRpc\Reflection; + +class ThrowsTag extends TypeDescriptionTag +{ +} diff --git a/vendor/gipfl/openrpc/src/Reflection/TypeDescriptionTag.php b/vendor/gipfl/openrpc/src/Reflection/TypeDescriptionTag.php new file mode 100644 index 0000000..fd090b2 --- /dev/null +++ b/vendor/gipfl/openrpc/src/Reflection/TypeDescriptionTag.php @@ -0,0 +1,27 @@ +<?php + +namespace gipfl\OpenRpc\Reflection; + +class TypeDescriptionTag extends Tag +{ + public $dataType; + + public $description; + + protected function parseTagValue($value) + { + if (empty($value)) { + return; + } + $parts = preg_split('/(\s+)/us', trim($value), 2, PREG_SPLIT_DELIM_CAPTURE); + + $this->dataType = array_shift($parts); + array_shift($parts); + + if (empty($parts)) { + return; + } + + $this->description = implode($parts); + } +} diff --git a/vendor/gipfl/openrpc/src/Server.php b/vendor/gipfl/openrpc/src/Server.php new file mode 100644 index 0000000..0d03c9f --- /dev/null +++ b/vendor/gipfl/openrpc/src/Server.php @@ -0,0 +1,74 @@ +<?php + +namespace gipfl\OpenRpc; + +use JsonSerializable; + +/** + * An object representing a Server. + */ +class Server implements JsonSerializable +{ + use SimpleJsonSerializer; + + /** + * REQUIRED. A name to be used as the canonical name for the server. + * + * @var string + */ + public $name; + + /** + * REQUIRED. A URL to the target host. This URL supports Server Variables and + * MAY be relative, to indicate that the host location is relative to the + * location where the OpenRPC document is being served. Server Variables are + * passed into the Runtime Expression to produce a server URL. + * + * Runtime expressions allow the user to define an expression which will + * evaluate to a string once the desired value(s) are known. They are used + * when the desired value of a link or server can only be constructed at + * run time. This mechanism is used by Link Objects and Server Variables. + * + * The runtime expression makes use of JSON Template Language syntax: + * + * https://tools.ietf.org/html/draft-jonas-json-template-language-01 + * + * Runtime expressions preserve the type of the referenced value. + * + * @var string RuntimeExpression + */ + public $url; + + /** + * A short summary of what the server is. + * + * @var string|null + */ + public $summary; + + /** + * An optional string describing the host designated by the URL. GitHub + * Flavored Markdown syntax MAY be used for rich text representation. + * + * @var string|null + */ + public $description; + + /** + * A map between a variable name and its value. The value is passed into + * the Runtime Expression to produce a server URL. + * + * @var ServerVariable Map[string, Server Variable Object] + */ + public $variables; + + /** + * @param string $name + * @param string $url + */ + public function __construct($name, $url) + { + $this->name = $name; + $this->url = $url; + } +} diff --git a/vendor/gipfl/openrpc/src/ServerVariable.php b/vendor/gipfl/openrpc/src/ServerVariable.php new file mode 100644 index 0000000..047dcf6 --- /dev/null +++ b/vendor/gipfl/openrpc/src/ServerVariable.php @@ -0,0 +1,46 @@ +<?php + +namespace gipfl\OpenRpc; + +use JsonSerializable; + +/** + * An object representing a Server Variable for server URL template substitution. + */ +class ServerVariable implements JsonSerializable +{ + use SimpleJsonSerializer; + + /** + * REQUIRED. The default value to use for substitution, which SHALL be sent + * if an alternate value is not supplied. Note this behavior is different + * than the Schema Object’s treatment of default values, because in those + * cases parameter values are optional. + * + * @var string + */ + public $default; + + /** + * An optional description for the server variable. GitHub Flavored Markdown + * syntax MAY be used for rich text representation. + * + * @var string|null + */ + public $description; + + /** + * An enumeration of string values to be used if the substitution options are from a limited set. + * + * @var string[] + */ + public $enum; + + /** + * @param string $default + */ + public function __construct($default) + { + $this->default = $default; + } +} diff --git a/vendor/gipfl/openrpc/src/SimpleJsonSerializer.php b/vendor/gipfl/openrpc/src/SimpleJsonSerializer.php new file mode 100644 index 0000000..0427c7b --- /dev/null +++ b/vendor/gipfl/openrpc/src/SimpleJsonSerializer.php @@ -0,0 +1,14 @@ +<?php + +namespace gipfl\OpenRpc; + +trait SimpleJsonSerializer +{ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return (object) array_filter(get_object_vars($this), function ($value) { + return $value !== null; + }); + } +} diff --git a/vendor/gipfl/openrpc/src/TagObject.php b/vendor/gipfl/openrpc/src/TagObject.php new file mode 100644 index 0000000..2d69d1d --- /dev/null +++ b/vendor/gipfl/openrpc/src/TagObject.php @@ -0,0 +1,48 @@ +<?php + +namespace gipfl\OpenRpc; + +use JsonSerializable; + +/** + * Adds metadata to a single tag that is used by the Method Object. It is not + * mandatory to have a Tag Object per tag defined in the Method Object instances + */ +class TagObject implements JsonSerializable +{ + use SimpleJsonSerializer; + + /** + * REQUIRED. The name of the tag. + * + * @var string + */ + public $name; + + /** + * A short summary of the tag. + * + * @var string|null + */ + public $summary; + + /** + * A verbose explanation for the tag. GitHub Flavored Markdown syntax MAY + * be used for rich text representation. + * + * @var string|null + */ + public $description; + + /** + * Additional external documentation for this tag. + * + * @var ExternalDocumentation + */ + public $externalDocs; + + public function __construct($name) + { + $this->name = $name; + } +} |