···11+<?php
22+33+namespace SocialDept\Schema\Contracts;
44+55+use Illuminate\Http\UploadedFile;
66+use SocialDept\Schema\Data\BlobReference;
77+88+interface BlobHandler
99+{
1010+ /**
1111+ * Upload blob and create reference.
1212+ */
1313+ public function upload(UploadedFile $file): BlobReference;
1414+1515+ /**
1616+ * Upload blob from path.
1717+ */
1818+ public function uploadFromPath(string $path): BlobReference;
1919+2020+ /**
2121+ * Upload blob from content.
2222+ */
2323+ public function uploadFromContent(string $content, string $mimeType): BlobReference;
2424+2525+ /**
2626+ * Download blob content.
2727+ */
2828+ public function download(BlobReference $blob): string;
2929+3030+ /**
3131+ * Generate signed URL for blob.
3232+ */
3333+ public function url(BlobReference $blob): string;
3434+3535+ /**
3636+ * Check if blob exists in storage.
3737+ */
3838+ public function exists(BlobReference $blob): bool;
3939+4040+ /**
4141+ * Delete blob from storage.
4242+ */
4343+ public function delete(BlobReference $blob): bool;
4444+}
+33
src/Contracts/DataGenerator.php
···11+<?php
22+33+namespace SocialDept\Schema\Contracts;
44+55+use SocialDept\Schema\Data\LexiconDocument;
66+77+interface DataGenerator
88+{
99+ /**
1010+ * Generate PHP class files from Lexicon definition.
1111+ */
1212+ public function generate(LexiconDocument $schema): string;
1313+1414+ /**
1515+ * Generate and write class file to disk.
1616+ */
1717+ public function generateAndSave(LexiconDocument $schema, string $outputPath): string;
1818+1919+ /**
2020+ * Generate class content without writing to disk.
2121+ */
2222+ public function preview(LexiconDocument $schema): string;
2323+2424+ /**
2525+ * Set the base namespace for generated classes.
2626+ */
2727+ public function setBaseNamespace(string $namespace): void;
2828+2929+ /**
3030+ * Set the output path for generated classes.
3131+ */
3232+ public function setOutputPath(string $path): void;
3333+}
+28
src/Contracts/LexiconParser.php
···11+<?php
22+33+namespace SocialDept\Schema\Contracts;
44+55+use SocialDept\Schema\Data\LexiconDocument;
66+77+interface LexiconParser
88+{
99+ /**
1010+ * Parse raw Lexicon JSON into structured objects.
1111+ */
1212+ public function parse(string $json): LexiconDocument;
1313+1414+ /**
1515+ * Parse Lexicon from array data.
1616+ */
1717+ public function parseArray(array $data): LexiconDocument;
1818+1919+ /**
2020+ * Validate Lexicon schema structure.
2121+ */
2222+ public function validate(array $data): bool;
2323+2424+ /**
2525+ * Resolve $ref references to other schemas.
2626+ */
2727+ public function resolveReference(string $ref, LexiconDocument $context): mixed;
2828+}
+28
src/Contracts/LexiconResolver.php
···11+<?php
22+33+namespace SocialDept\Schema\Contracts;
44+55+use SocialDept\Schema\Data\LexiconDocument;
66+77+interface LexiconResolver
88+{
99+ /**
1010+ * Resolve NSID to Lexicon schema via DNS and XRPC.
1111+ */
1212+ public function resolve(string $nsid): LexiconDocument;
1313+1414+ /**
1515+ * Perform DNS TXT lookup for _lexicon.{authority}.
1616+ */
1717+ public function lookupDns(string $authority): ?string;
1818+1919+ /**
2020+ * Retrieve schema via XRPC from PDS.
2121+ */
2222+ public function retrieveSchema(string $pdsEndpoint, string $did, string $nsid): array;
2323+2424+ /**
2525+ * Check if DNS resolution is enabled.
2626+ */
2727+ public function isEnabled(): bool;
2828+}
+30
src/Contracts/LexiconValidator.php
···11+<?php
22+33+namespace SocialDept\Schema\Contracts;
44+55+use SocialDept\Schema\Data\LexiconDocument;
66+77+interface LexiconValidator
88+{
99+ /**
1010+ * Validate data against Lexicon schema.
1111+ */
1212+ public function validate(array $data, LexiconDocument $schema): bool;
1313+1414+ /**
1515+ * Validate and return errors.
1616+ *
1717+ * @return array<string, array<string>>
1818+ */
1919+ public function validateWithErrors(array $data, LexiconDocument $schema): array;
2020+2121+ /**
2222+ * Validate a specific field.
2323+ */
2424+ public function validateField(mixed $value, string $field, LexiconDocument $schema): bool;
2525+2626+ /**
2727+ * Set validation mode (strict, optimistic, lenient).
2828+ */
2929+ public function setMode(string $mode): void;
3030+}
+35
src/Contracts/SchemaRepository.php
···11+<?php
22+33+namespace SocialDept\Schema\Contracts;
44+55+use SocialDept\Schema\Data\LexiconDocument;
66+77+interface SchemaRepository
88+{
99+ /**
1010+ * Find schema by NSID.
1111+ */
1212+ public function find(string $nsid): ?LexiconDocument;
1313+1414+ /**
1515+ * Load schema from multiple sources.
1616+ */
1717+ public function load(string $nsid): LexiconDocument;
1818+1919+ /**
2020+ * Check if schema exists.
2121+ */
2222+ public function exists(string $nsid): bool;
2323+2424+ /**
2525+ * Get all available schema NSIDs.
2626+ *
2727+ * @return array<string>
2828+ */
2929+ public function all(): array;
3030+3131+ /**
3232+ * Clear cached schemas.
3333+ */
3434+ public function clearCache(?string $nsid = null): void;
3535+}
+33
src/Contracts/TypeMapper.php
···11+<?php
22+33+namespace SocialDept\Schema\Contracts;
44+55+interface TypeMapper
66+{
77+ /**
88+ * Map Lexicon type to PHP type.
99+ */
1010+ public function toPhpType(string $lexiconType): string;
1111+1212+ /**
1313+ * Map Lexicon type to PHPDoc type.
1414+ */
1515+ public function toPhpDocType(string $lexiconType): string;
1616+1717+ /**
1818+ * Handle union types.
1919+ *
2020+ * @param array<string> $types
2121+ */
2222+ public function unionType(array $types): string;
2323+2424+ /**
2525+ * Check if type is nullable.
2626+ */
2727+ public function isNullable(array $definition): bool;
2828+2929+ /**
3030+ * Resolve type reference.
3131+ */
3232+ public function resolveReference(string $ref): string;
3333+}