1: <?php
2:
3: declare(strict_types=1);
4:
5: /**
6: * This file is part of the Nexus MCP SDK package.
7: *
8: * (c) 2026 John Paul E. Balandan, CPA <paulbalandan@gmail.com>
9: *
10: * For the full copyright and license information, please view
11: * the LICENSE file that was distributed with this source code.
12: */
13:
14: namespace Nexus\Mcp\Core\Schema\Resource;
15:
16: use Nexus\Assert\Assert;
17: use Nexus\Mcp\Core\Schema\MetaObject;
18: use Nexus\Mcp\Core\Schema\MetaObject\PayloadMetaObject;
19:
20: /**
21: * Binary resource contents, whose `blob` payload carries a base64-encoded representation of the data.
22: *
23: * @extends ResourceContents<array{
24: * uri: non-empty-string,
25: * blob: string,
26: * mimeType?: non-empty-string,
27: * _meta?: template-type<PayloadMetaObject, MetaObject, 'T'>,
28: * }>
29: *
30: * @see https://modelcontextprotocol.io/specification/2026-07-28/schema#blobresourcecontents
31: */
32: final readonly class BlobResourceContents extends ResourceContents
33: {
34: public function __construct(
35: string $uri,
36: public string $blob,
37: ?string $mimeType = null,
38: PayloadMetaObject $meta = new PayloadMetaObject(),
39: ) {
40: parent::__construct(uri: $uri, mimeType: $mimeType, meta: $meta);
41: }
42:
43: #[\Override]
44: public static function fromArray(array $data): static
45: {
46: Assert::that($data)->hasOffset('uri', 'blob resource contents is missing the required "uri" key.');
47: $uri = $data['uri'];
48: Assert::that($uri)->isNonEmptyString('blob resource contents "uri" must be a non-empty string, {type} given.');
49:
50: Assert::that($data)->hasOffset('blob', 'blob resource contents is missing the required "blob" key.');
51: $blob = $data['blob'];
52: Assert::that($blob)->isString('blob resource contents "blob" must be a string, {type} given.');
53:
54: $mimeType = $data['mimeType'] ?? null;
55: Assert::that($mimeType)->nullOr()->isNonEmptyString('blob resource contents "mimeType" must be a non-empty string or null, {type} given.');
56:
57: $meta = new PayloadMetaObject();
58:
59: if (\array_key_exists('_meta', $data)) {
60: Assert::that($data['_meta'])
61: ->isArray('blob resource contents "_meta" must be an object, {type} given.')
62: ->not()->isNonEmptyList('blob resource contents "_meta" must be a string-keyed object.')
63: ;
64: $meta = PayloadMetaObject::fromArray($data['_meta']);
65: }
66:
67: return new self(uri: $uri, blob: $blob, mimeType: $mimeType, meta: $meta);
68: }
69:
70: #[\Override]
71: public function toArray(): array
72: {
73: $data = [
74: 'uri' => $this->uri,
75: 'blob' => $this->blob,
76: ];
77:
78: if (null !== $this->mimeType) {
79: $data['mimeType'] = $this->mimeType;
80: }
81:
82: $meta = $this->meta->toArray();
83:
84: if ([] !== $meta) {
85: $data['_meta'] = $meta;
86: }
87:
88: return $data;
89: }
90: }
91: