diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 1e5b181..a2b062b 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -7,5 +7,11 @@ return (new Config()) ->setParallelConfig(ParallelConfigFactory::detect()) ->setFinder(Finder::create()->in([__DIR__.'/src', __DIR__.'/tests'])) - ->setRules(['@PhpCsFixer' => true, 'phpdoc_align' => false, 'new_with_parentheses' => ['named_class' => false]]) + ->setRules([ + '@PhpCsFixer' => true, + 'phpdoc_align' => false, + 'new_with_parentheses' => ['named_class' => false], + 'ordered_types' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], + 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], + ]) ; diff --git a/.stats.yml b/.stats.yml index 636c6f9..6804ffb 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 15 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/scrapegraphai%2Fscrapegraphai-969ebada41127057e4cda129b2e7206224743b5c7fd33aa8ae062ff71b775ac9.yml -openapi_spec_hash: 2b2c2c684e6f6885398efca5f2b1f854 -config_hash: 30d69c79e34a1ea6a0405573ce30d927 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/scrapegraphai%2Fscrapegraphai-633fdeab6abaefbe666099e8f86ce6b2acc9dacff1c33a80813bb04e8e437229.yml +openapi_spec_hash: f41ec90694ca8e7233bd20cc7ff1afbf +config_hash: 6889576ba0fdc14f2c71cea09a60a0f6 diff --git a/README.md b/README.md index 193884d..8a49fb1 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ > > This library has not yet been exhaustively tested in production environments and may be missing some features you'd expect in a stable release. As we continue development, there may be breaking changes that require updates to your code. > -> **We'd love your feedback!** Please share any suggestions, bug reports, feature requests, or general thoughts by [filing an issue](https://www.github.com/stainless-sdks/scrapegraphai-php/issues/new). +> **We'd love your feedback!** Please share any suggestions, bug reports, feature requests, or general thoughts by [filing an issue](https://www.github.com/ScrapeGraphAI/scrapegraphai-php/issues/new). The Scrapegraphai PHP library provides convenient access to the Scrapegraphai REST API from any PHP 8.1.0+ application. @@ -19,12 +19,14 @@ The REST API documentation can be found on [scrapegraphai.com](https://scrapegra To use this package, install via Composer by adding the following to your application's `composer.json`: + + ```json { "repositories": [ { "type": "vcs", - "url": "git@github.com:stainless-sdks/scrapegraphai-php.git" + "url": "git@github.com:ScrapeGraphAI/scrapegraphai-php.git" } ], "require": { @@ -33,27 +35,36 @@ To use this package, install via Composer by adding the following to your applic } ``` + + ## Usage +This library uses named parameters to specify optional arguments. +Parameters with a default value must be set by name. + ```php smartscraper->create( userPrompt: "Extract the product name, price, and description" ); -$completedSmartscraper = $client->smartscraper->create($params); - var_dump($completedSmartscraper->request_id); ``` +### Value Objects + +It is recommended to use the static `with` constructor `Dog::with(name: "Joey")` +and named parameters to initialize value objects. + +However, builders are also provided `(new Dog)->withName("Joey")`. + ### Handling errors When the library is unable to connect to the API, or if the API returns a non-success status code (i.e., 4xx or 5xx response), a subclass of `Scrapegraphai\Errors\APIError` will be thrown: @@ -62,21 +73,19 @@ When the library is unable to connect to the API, or if the API returns a non-su smartscraper->create($params); + $completedSmartscraper = $client->smartscraper->create( + userPrompt: "Extract the product name, price, and description" + ); } catch (APIConnectionError $e) { - echo "The server could not be reached", PHP_EOL; - var_dump($e->getPrevious()); + echo "The server could not be reached", PHP_EOL; + var_dump($e->getPrevious()); } catch (RateLimitError $_) { - echo "A 429 status code was received; we should back off a bit.", PHP_EOL; + echo "A 429 status code was received; we should back off a bit.", PHP_EOL; } catch (APIStatusError $e) { - echo "Another non-200-range status code was received", PHP_EOL; - var_dump($e->status); + echo "Another non-200-range status code was received", PHP_EOL; + echo $e->getMessage(); } ``` @@ -109,18 +118,15 @@ You can use the `max_retries` option to configure or disable this: use Scrapegraphai\Client; use Scrapegraphai\RequestOptions; -use Scrapegraphai\Smartscraper\SmartscraperCreateParams; // Configure the default for all requests: $client = new Client(maxRetries: 0); -$params = SmartscraperCreateParams::from( - userPrompt: "Extract the product name, price, and description" -); // Or, configure per-request: -$result = $client - ->smartscraper - ->create($params, new RequestOptions(maxRetries: 5)); +$result = $client->smartscraper->create( + userPrompt: "Extract the product name, price, and description", + new RequestOptions(maxRetries: 5), +); ``` ## Advanced concepts @@ -137,15 +143,9 @@ Note: the `extra_` parameters of the same name overrides the documented paramete smartscraper - ->create( - $params, +$completedSmartscraper = $client->smartscraper->create( + userPrompt: "Extract the product name, price, and description", new RequestOptions( extraQueryParams: ["my_query_parameter" => "value"], extraBodyParams: ["my_body_parameter" => "value"], @@ -236,4 +236,4 @@ PHP 8.1.0 or higher. ## Contributing -See [the contributing documentation](https://github.com/stainless-sdks/scrapegraphai-php/tree/main/CONTRIBUTING.md). +See [the contributing documentation](https://github.com/ScrapeGraphAI/scrapegraphai-php/tree/main/CONTRIBUTING.md). diff --git a/src/Client.php b/src/Client.php index daf0fc9..410fd16 100644 --- a/src/Client.php +++ b/src/Client.php @@ -5,15 +5,15 @@ namespace Scrapegraphai; use Scrapegraphai\Core\BaseClient; -use Scrapegraphai\Crawl\CrawlService; -use Scrapegraphai\Credits\CreditsService; -use Scrapegraphai\Feedback\FeedbackService; -use Scrapegraphai\GenerateSchema\GenerateSchemaService; -use Scrapegraphai\Healthz\HealthzService; -use Scrapegraphai\Markdownify\MarkdownifyService; -use Scrapegraphai\Searchscraper\SearchscraperService; -use Scrapegraphai\Smartscraper\SmartscraperService; -use Scrapegraphai\Validate\ValidateService; +use Scrapegraphai\Services\CrawlService; +use Scrapegraphai\Services\CreditsService; +use Scrapegraphai\Services\FeedbackService; +use Scrapegraphai\Services\GenerateSchemaService; +use Scrapegraphai\Services\HealthzService; +use Scrapegraphai\Services\MarkdownifyService; +use Scrapegraphai\Services\SearchscraperService; +use Scrapegraphai\Services\SmartscraperService; +use Scrapegraphai\Services\ValidateService; class Client extends BaseClient { diff --git a/src/Contracts/CrawlContract.php b/src/Contracts/CrawlContract.php index beeb74e..dc2c648 100644 --- a/src/Contracts/CrawlContract.php +++ b/src/Contracts/CrawlContract.php @@ -4,7 +4,6 @@ namespace Scrapegraphai\Contracts; -use Scrapegraphai\Crawl\CrawlStartParams; use Scrapegraphai\Crawl\CrawlStartParams\Rules; use Scrapegraphai\RequestOptions; use Scrapegraphai\Responses\Crawl\CrawlGetResultsResponse; @@ -18,20 +17,26 @@ public function retrieveResults( ): CrawlGetResultsResponse; /** - * @param array{ - * url: string, - * depth?: int, - * extractionMode?: bool, - * maxPages?: int, - * prompt?: null|string, - * renderHeavyJs?: bool, - * rules?: Rules, - * schema?: mixed, - * sitemap?: bool, - * }|CrawlStartParams $params + * @param string $url Starting URL for crawling + * @param int $depth Maximum crawl depth from starting URL + * @param bool $extractionMode Use AI extraction (true) or markdown conversion (false) + * @param int $maxPages Maximum number of pages to crawl + * @param string|null $prompt Extraction prompt (required if extraction_mode is true) + * @param bool $renderHeavyJs Enable heavy JavaScript rendering + * @param Rules $rules + * @param mixed $schema Output schema for extraction + * @param bool $sitemap Use sitemap for crawling */ public function start( - array|CrawlStartParams $params, - ?RequestOptions $requestOptions = null + $url, + $depth = null, + $extractionMode = null, + $maxPages = null, + $prompt = null, + $renderHeavyJs = null, + $rules = null, + $schema = null, + $sitemap = null, + ?RequestOptions $requestOptions = null, ): CrawlStartResponse; } diff --git a/src/Contracts/FeedbackContract.php b/src/Contracts/FeedbackContract.php index d6d9947..4008f17 100644 --- a/src/Contracts/FeedbackContract.php +++ b/src/Contracts/FeedbackContract.php @@ -4,19 +4,20 @@ namespace Scrapegraphai\Contracts; -use Scrapegraphai\Feedback\FeedbackSubmitParams; use Scrapegraphai\RequestOptions; use Scrapegraphai\Responses\Feedback\FeedbackSubmitResponse; interface FeedbackContract { /** - * @param array{ - * rating: int, requestID: string, feedbackText?: null|string - * }|FeedbackSubmitParams $params + * @param int $rating Rating score + * @param string $requestID Request to provide feedback for + * @param string|null $feedbackText Optional feedback comments */ public function submit( - array|FeedbackSubmitParams $params, + $rating, + $requestID, + $feedbackText = null, ?RequestOptions $requestOptions = null, ): FeedbackSubmitResponse; } diff --git a/src/Contracts/GenerateSchemaContract.php b/src/Contracts/GenerateSchemaContract.php index fd3f522..5970bcb 100644 --- a/src/Contracts/GenerateSchemaContract.php +++ b/src/Contracts/GenerateSchemaContract.php @@ -4,7 +4,6 @@ namespace Scrapegraphai\Contracts; -use Scrapegraphai\GenerateSchema\GenerateSchemaCreateParams; use Scrapegraphai\RequestOptions; use Scrapegraphai\Responses\GenerateSchema\GenerateSchemaGetResponse\CompletedSchemaGenerationResponse; use Scrapegraphai\Responses\GenerateSchema\GenerateSchemaGetResponse\FailedSchemaGenerationResponse; @@ -13,12 +12,12 @@ interface GenerateSchemaContract { /** - * @param array{ - * userPrompt: string, existingSchema?: mixed - * }|GenerateSchemaCreateParams $params + * @param string $userPrompt Natural language description of desired schema + * @param mixed $existingSchema Existing schema to modify or extend */ public function create( - array|GenerateSchemaCreateParams $params, + $userPrompt, + $existingSchema = null, ?RequestOptions $requestOptions = null, ): GenerateSchemaNewResponse; diff --git a/src/Contracts/MarkdownifyContract.php b/src/Contracts/MarkdownifyContract.php index 8737c95..2cbba13 100644 --- a/src/Contracts/MarkdownifyContract.php +++ b/src/Contracts/MarkdownifyContract.php @@ -5,19 +5,20 @@ namespace Scrapegraphai\Contracts; use Scrapegraphai\Markdownify\CompletedMarkdownify; -use Scrapegraphai\Markdownify\MarkdownifyConvertParams; use Scrapegraphai\RequestOptions; use Scrapegraphai\Responses\Markdownify\MarkdownifyGetStatusResponse\FailedMarkdownifyResponse; interface MarkdownifyContract { /** - * @param array{ - * websiteURL: string, headers?: array, steps?: list - * }|MarkdownifyConvertParams $params + * @param string $websiteURL URL to convert to markdown + * @param array $headers + * @param list $steps Interaction steps before conversion */ public function convert( - array|MarkdownifyConvertParams $params, + $websiteURL, + $headers = null, + $steps = null, ?RequestOptions $requestOptions = null, ): CompletedMarkdownify; diff --git a/src/Contracts/SearchscraperContract.php b/src/Contracts/SearchscraperContract.php index 2f7a099..82dac5f 100644 --- a/src/Contracts/SearchscraperContract.php +++ b/src/Contracts/SearchscraperContract.php @@ -7,20 +7,20 @@ use Scrapegraphai\RequestOptions; use Scrapegraphai\Responses\Searchscraper\SearchscraperGetStatusResponse\FailedSearchScraperResponse; use Scrapegraphai\Searchscraper\CompletedSearchScraper; -use Scrapegraphai\Searchscraper\SearchscraperCreateParams; interface SearchscraperContract { /** - * @param array{ - * userPrompt: string, - * headers?: array, - * numResults?: int, - * outputSchema?: mixed, - * }|SearchscraperCreateParams $params + * @param string $userPrompt Search query and extraction instruction + * @param array $headers + * @param int $numResults Number of websites to scrape from search results + * @param mixed $outputSchema JSON schema for structured output */ public function create( - array|SearchscraperCreateParams $params, + $userPrompt, + $headers = null, + $numResults = null, + $outputSchema = null, ?RequestOptions $requestOptions = null, ): CompletedSearchScraper; diff --git a/src/Contracts/SmartscraperContract.php b/src/Contracts/SmartscraperContract.php index 9b99f80..4df2546 100644 --- a/src/Contracts/SmartscraperContract.php +++ b/src/Contracts/SmartscraperContract.php @@ -7,26 +7,32 @@ use Scrapegraphai\RequestOptions; use Scrapegraphai\Smartscraper\CompletedSmartscraper; use Scrapegraphai\Smartscraper\FailedSmartscraper; -use Scrapegraphai\Smartscraper\SmartscraperCreateParams; interface SmartscraperContract { /** - * @param array{ - * userPrompt: string, - * cookies?: array, - * headers?: array, - * numberOfScrolls?: int, - * outputSchema?: mixed, - * renderHeavyJs?: bool, - * steps?: list, - * totalPages?: int, - * websiteHTML?: string, - * websiteURL?: string, - * }|SmartscraperCreateParams $params + * @param string $userPrompt Extraction instruction for the LLM + * @param array $cookies Cookies to include in the request + * @param array $headers HTTP headers to include in the request + * @param int $numberOfScrolls Number of infinite scroll operations to perform + * @param mixed $outputSchema JSON schema defining the expected output structure + * @param bool $renderHeavyJs Enable heavy JavaScript rendering + * @param list $steps Website interaction steps (e.g., clicking buttons) + * @param int $totalPages Number of pages to process for pagination + * @param string $websiteHTML HTML content to process (max 2MB, mutually exclusive with website_url) + * @param string $websiteURL URL to scrape (mutually exclusive with website_html) */ public function create( - array|SmartscraperCreateParams $params, + $userPrompt, + $cookies = null, + $headers = null, + $numberOfScrolls = null, + $outputSchema = null, + $renderHeavyJs = null, + $steps = null, + $totalPages = null, + $websiteHTML = null, + $websiteURL = null, ?RequestOptions $requestOptions = null, ): CompletedSmartscraper; diff --git a/src/Core/Adapters/GeneratorStream.php b/src/Core/Adapters/GeneratorStream.php deleted file mode 100644 index 052701b..0000000 --- a/src/Core/Adapters/GeneratorStream.php +++ /dev/null @@ -1,107 +0,0 @@ - $st - */ - public function __construct(private \Generator $st) {} - - public function __toString(): string - { - try { - return $this->getContents(); - } catch (\Throwable) { - return ''; - } - } - - public function getSize(): ?int - { - return null; - } - - public function eof(): bool - { - return !strlen($this->buf) && !$this->st->valid(); - } - - public function close(): void - { - $ex = new class() extends \Exception {}; - - try { - $this->st->throw(new $ex); - } catch (\Throwable) { - } - } - - public function detach(): null - { - $this->buf = ''; - $this->close(); - - return null; - } - - public function tell(): int - { - return $this->pos; - } - - public function rewind(): void - { - $this->buf = ''; - $this->st->rewind(); - } - - public function isSeekable(): bool - { - return false; - } - - public function seek(int $offset, int $whence = SEEK_SET): void {} - - public function isWritable(): bool - { - return false; - } - - public function write(string $string): int - { - return 0; - } - - public function isReadable(): bool - { - return !$this->eof(); - } - - public function read(int $length): string - { - return ''; - } - - public function getContents(): string - { - foreach ($this->st as $chunk) { - $this->buf .= $chunk; - } - - return $this->buf; - } - - public function getMetadata(?string $key = null): mixed - { - return null; - } -} diff --git a/src/Core/Attributes/Api.php b/src/Core/Attributes/Api.php index a8b0d69..a1ec512 100644 --- a/src/Core/Attributes/Api.php +++ b/src/Core/Attributes/Api.php @@ -6,6 +6,8 @@ use Scrapegraphai\Core\Conversion\Contracts\Converter; use Scrapegraphai\Core\Conversion\Contracts\ConverterSource; +use Scrapegraphai\Core\Conversion\ListOf; +use Scrapegraphai\Core\Conversion\MapOf; /** * @internal @@ -14,23 +16,26 @@ final class Api { /** - * @var null|class-string|Converter|string + * @var class-string|Converter|string|null */ - public readonly null|Converter|string $type; + public readonly Converter|string|null $type; /** - * @param null|class-string|Converter|string $type - * @param null|class-string|Converter $enum - * @param null|class-string|Converter|string $union + * @param class-string|Converter|string|null $type + * @param class-string|Converter|null $enum + * @param class-string|Converter|string|null $union + * @param class-string|Converter|string|null $list */ public function __construct( public readonly ?string $apiName = null, - null|Converter|string $type = null, - null|Converter|string $enum = null, - null|Converter|string $union = null, + Converter|string|null $type = null, + Converter|string|null $enum = null, + Converter|string|null $union = null, + Converter|string|null $list = null, + Converter|string|null $map = null, public readonly bool $nullable = false, public readonly bool $optional = false, ) { - $this->type = $type ?? $enum ?? $union; + $this->type = $type ?? $enum ?? $union ?? ($list ? new ListOf($list) : ($map ? new MapOf($map) : null)); } } diff --git a/src/Core/BaseClient.php b/src/Core/BaseClient.php index 04e3a10..29e5b92 100644 --- a/src/Core/BaseClient.php +++ b/src/Core/BaseClient.php @@ -26,10 +26,10 @@ class BaseClient protected RequestFactoryInterface $requestFactory; - protected ClientInterface $requester; + protected ClientInterface $transporter; /** - * @param array|string> $headers + * @param array|null> $headers */ public function __construct( protected array $headers, @@ -41,17 +41,17 @@ public function __construct( $this->requestFactory = Psr17FactoryDiscovery::findRequestFactory(); $this->baseUrl = $this->uriFactory->createUri($baseUrl); - $this->requester = Psr18ClientDiscovery::find(); + $this->transporter = Psr18ClientDiscovery::find(); } /** - * @param list|string $path + * @param string|list $path * @param array $query * @param array $headers */ public function request( string $method, - array|string $path, + string|array $path, array $query = [], array $headers = [], mixed $body = null, @@ -88,27 +88,27 @@ protected function authHeaders(): array } /** - * @param list|string $path + * @param string|list $path * @param array $query - * @param array|string> $headers - * @param null|array{ - * timeout?: null|float, - * maxRetries?: null|int, - * initialRetryDelay?: null|float, - * maxRetryDelay?: null|float, - * extraHeaders?: null|list, - * extraQueryParams?: null|list, - * extraBodyParams?: null|list, - * }|RequestOptions $opts + * @param array|null> $headers + * @param array{ + * timeout?: float|null, + * maxRetries?: int|null, + * initialRetryDelay?: float|null, + * maxRetryDelay?: float|null, + * extraHeaders?: list|null, + * extraQueryParams?: list|null, + * extraBodyParams?: list|null, + * }|RequestOptions|null $opts * * @return array{RequestInterface, RequestOptions} */ protected function buildRequest( string $method, - array|string $path, + string|array $path, array $query, array $headers, - null|array|RequestOptions $opts, + array|RequestOptions|null $opts, ): array { $opts = [...$this->options->__serialize(), ...RequestOptions::parse($opts)->__serialize()]; $options = new RequestOptions(...$opts); @@ -119,7 +119,7 @@ protected function buildRequest( $mergedQuery = array_merge_recursive($query, $options->extraQueryParams); $uri = Util::joinUri($this->baseUrl, path: $parsedPath, query: $mergedQuery); - /** @var array|string> $mergedHeaders */ + /** @var array> $mergedHeaders */ $mergedHeaders = [...$this->headers, ...$this->authHeaders(), ...$headers, @@ -146,9 +146,8 @@ protected function followRedirect( } /** - * @param null|array|bool|float|int|resource|string|\Traversable< - * mixed - * > $data + * @param bool|int|float|string|resource|\Traversable|array|null $data */ protected function sendRequest( RequestInterface $req, @@ -158,7 +157,7 @@ protected function sendRequest( int $redirectCount, ): ResponseInterface { $req = Util::withSetBody($this->streamFactory, req: $req, body: $data); - $rsp = $this->requester->sendRequest($req); + $rsp = $this->transporter->sendRequest($req); $code = $rsp->getStatusCode(); if ($code >= 300 && $code < 400) { @@ -172,7 +171,7 @@ protected function sendRequest( } if ($code >= 400 && $code < 500) { - throw APIStatusError::from(null, request: $req, response: $rsp); + throw APIStatusError::from(request: $req, response: $rsp); } if ($code >= 500 && $retryCount < $opts->maxRetries) { diff --git a/src/Core/Concerns/Page.php b/src/Core/Concerns/Page.php deleted file mode 100644 index a355f9d..0000000 --- a/src/Core/Concerns/Page.php +++ /dev/null @@ -1,22 +0,0 @@ -|self $params - * @param null|array|RequestOptions $options + * @param array|self|null $params + * @param array|RequestOptions|null $options * * @return array{array, array{ * timeout: float, @@ -27,7 +27,7 @@ trait Params * extraBodyParams: list, * }} */ - public static function parseRequest(null|array|self $params, null|array|RequestOptions $options): array + public static function parseRequest(array|self|null $params, array|RequestOptions|null $options): array { $converter = self::converter(); $state = new DumpState; diff --git a/src/Core/Concerns/Union.php b/src/Core/Concerns/SdkUnion.php similarity index 98% rename from src/Core/Concerns/Union.php rename to src/Core/Concerns/SdkUnion.php index e34110a..cd54e03 100644 --- a/src/Core/Concerns/Union.php +++ b/src/Core/Concerns/SdkUnion.php @@ -11,7 +11,7 @@ /** * @internal */ -trait Union +trait SdkUnion { private static Converter $converter; diff --git a/src/Core/Contracts/BasePage.php b/src/Core/Contracts/BasePage.php index ab70baa..3032525 100644 --- a/src/Core/Contracts/BasePage.php +++ b/src/Core/Contracts/BasePage.php @@ -4,13 +4,19 @@ namespace Scrapegraphai\Core\Contracts; +use Psr\Http\Message\ResponseInterface; +use Scrapegraphai\Core\BaseClient; +use Scrapegraphai\Core\Pagination\PageRequestOptions; + /** * @internal */ -interface BasePage extends \Stringable +interface BasePage { - /** - * @return \Traversable - */ - public function pagingEachItem(): \Traversable; + public function __construct( + BaseClient $client, + PageRequestOptions $options, + ResponseInterface $response, + mixed $body, + ); } diff --git a/src/Core/Contracts/CloseableStream.php b/src/Core/Contracts/CloseableStream.php new file mode 100644 index 0000000..c7d5635 --- /dev/null +++ b/src/Core/Contracts/CloseableStream.php @@ -0,0 +1,19 @@ + + */ +interface CloseableStream extends \IteratorAggregate +{ + /** + * Manually force the stream to close early. + * Iterating through will automatically close as well. + */ + public function close(): void; +} diff --git a/src/Core/Conversion/Concerns/ArrayOf.php b/src/Core/Conversion/Concerns/ArrayOf.php index ef71a03..46ac460 100644 --- a/src/Core/Conversion/Concerns/ArrayOf.php +++ b/src/Core/Conversion/Concerns/ArrayOf.php @@ -15,12 +15,12 @@ */ trait ArrayOf { - private readonly null|Converter|ConverterSource|string $type; + private readonly Converter|ConverterSource|string|null $type; public function __construct( - null|Converter|ConverterSource|string $type = null, - null|Converter|ConverterSource|string $enum = null, - null|Converter|ConverterSource|string $union = null, + Converter|ConverterSource|string|null $type = null, + Converter|ConverterSource|string|null $enum = null, + Converter|ConverterSource|string|null $union = null, private readonly bool $nullable = false, ) { $this->type = $type ?? $enum ?? $union; diff --git a/src/Core/Conversion/EnumOf.php b/src/Core/Conversion/EnumOf.php index 501159e..19a71bc 100644 --- a/src/Core/Conversion/EnumOf.php +++ b/src/Core/Conversion/EnumOf.php @@ -15,7 +15,7 @@ final class EnumOf implements Converter private readonly string $type; /** - * @param list $members + * @param list $members */ public function __construct(private readonly array $members) { diff --git a/src/Core/Conversion/PropertyInfo.php b/src/Core/Conversion/PropertyInfo.php index 7098314..f19391a 100644 --- a/src/Core/Conversion/PropertyInfo.php +++ b/src/Core/Conversion/PropertyInfo.php @@ -46,9 +46,9 @@ public function __construct(public readonly \ReflectionProperty $property) } /** - * @param null|array|Converter|ConverterSource|\ReflectionType|string $type + * @param array|Converter|ConverterSource|\ReflectionType|string|null $type */ - private static function parse(null|array|Converter|ConverterSource|\ReflectionType|string $type): Converter|ConverterSource|string + private static function parse(array|Converter|ConverterSource|\ReflectionType|string|null $type): Converter|ConverterSource|string { if (is_string($type) || $type instanceof Converter) { return $type; diff --git a/src/Core/Conversion/UnionOf.php b/src/Core/Conversion/UnionOf.php index c302fc0..1ef8a1b 100644 --- a/src/Core/Conversion/UnionOf.php +++ b/src/Core/Conversion/UnionOf.php @@ -77,7 +77,7 @@ public function dump(mixed $value, DumpState $state): mixed private function resolveVariant( mixed $value, - ): null|Converter|ConverterSource|string { + ): Converter|ConverterSource|string|null { if ($value instanceof BaseModel) { return $value::class; } diff --git a/src/Core/Pagination/AbstractPage.php b/src/Core/Pagination/AbstractPage.php index 4c4ca93..2206812 100644 --- a/src/Core/Pagination/AbstractPage.php +++ b/src/Core/Pagination/AbstractPage.php @@ -6,7 +6,7 @@ use Psr\Http\Message\ResponseInterface; use Scrapegraphai\Core\BaseClient; -use Scrapegraphai\Core\Concerns\Page; +use Scrapegraphai\Core\Contracts\BasePage; use Scrapegraphai\Errors\Error; /** @@ -16,7 +16,7 @@ * * @implements \IteratorAggregate */ -abstract class AbstractPage implements \IteratorAggregate, Page +abstract class AbstractPage implements \IteratorAggregate, BasePage { public function __construct( protected BaseClient $client, diff --git a/src/Core/Util.php b/src/Core/Util.php index 6f64612..88c9be0 100644 --- a/src/Core/Util.php +++ b/src/Core/Util.php @@ -45,11 +45,11 @@ public static function array_transform_keys(array $array, array $map): array } /** - * @param callable|int|list|string $key + * @param string|int|list|callable $key */ public static function dig( mixed $array, - array|callable|int|string $key + string|int|array|callable $key ): mixed { if (is_callable($key)) { return $key($array); @@ -71,9 +71,9 @@ public static function dig( } /** - * @param list|string $path + * @param string|list $path */ - public static function parsePath(array|string $path): string + public static function parsePath(string|array $path): string { if (is_string($path)) { return $path; @@ -124,7 +124,7 @@ public static function joinUri( } /** - * @param array|string> $headers + * @param array|null> $headers */ public static function withSetHeaders( RequestInterface $req, @@ -165,9 +165,8 @@ public static function streamIterator(StreamInterface $stream): \Iterator } /** - * @param null|array|bool|float|int|resource|string|\Traversable< - * mixed - * > $body + * @param bool|int|float|string|resource|\Traversable|array|null $body * * @return array{string, \Generator} */ @@ -202,9 +201,8 @@ public static function encodeMultipartStreaming(mixed $body): array } /** - * @param null|array|bool|float|int|resource|string|\Traversable< - * mixed - * > $body + * @param bool|int|float|string|resource|\Traversable|array|null $body */ public static function withSetBody( StreamFactoryInterface $factory, @@ -265,13 +263,13 @@ public static function decodeLines(\Iterator $stream): \Iterator /** * @param \Iterator $lines * - * @return \Iterator< + * @return \Generator< * array{ - * event?: null|string, data?: null|string, id?: null|string, retry?: null|int + * event?: string|null, data?: string|null, id?: string|null, retry?: int|null * }, * > */ - public static function decodeSSE(\Iterator $lines): \Iterator + public static function decodeSSE(\Iterator $lines): \Generator { $blank = ['event' => null, 'data' => null, 'id' => null, 'retry' => null]; $acc = []; @@ -349,6 +347,23 @@ public static function decodeContent(MessageInterface $rsp): mixed return self::streamIterator($body); } + /** + * @param array $arr + * @param list $keys + * + * @return array + */ + public static function array_filter_null(array $arr, array $keys): array + { + foreach ($keys as $key) { + if (array_key_exists($key, $arr) && is_null($arr[$key])) { + unset($arr[$key]); + } + } + + return $arr; + } + /** * @param list $closing * diff --git a/src/Crawl/CrawlService.php b/src/Crawl/CrawlService.php deleted file mode 100644 index b1f7254..0000000 --- a/src/Crawl/CrawlService.php +++ /dev/null @@ -1,71 +0,0 @@ -client->request( - method: 'get', - path: ['crawl/%1$s', $taskID], - options: $requestOptions - ); - - // @phpstan-ignore-next-line; - return Conversion::coerce(CrawlGetResultsResponse::class, value: $resp); - } - - /** - * Initiate comprehensive website crawling with sitemap support. - * Supports both AI extraction mode and markdown conversion mode. - * Returns a task ID for async processing. - * - * @param array{ - * url: string, - * depth?: int, - * extractionMode?: bool, - * maxPages?: int, - * prompt?: null|string, - * renderHeavyJs?: bool, - * rules?: Rules, - * schema?: mixed, - * sitemap?: bool, - * }|CrawlStartParams $params - */ - public function start( - array|CrawlStartParams $params, - ?RequestOptions $requestOptions = null - ): CrawlStartResponse { - [$parsed, $options] = CrawlStartParams::parseRequest( - $params, - $requestOptions - ); - $resp = $this->client->request( - method: 'post', - path: 'crawl', - body: (object) $parsed, - options: $options - ); - - // @phpstan-ignore-next-line; - return Conversion::coerce(CrawlStartResponse::class, value: $resp); - } -} diff --git a/src/Crawl/CrawlStartParams.php b/src/Crawl/CrawlStartParams.php index e6de992..3bbcb52 100644 --- a/src/Crawl/CrawlStartParams.php +++ b/src/Crawl/CrawlStartParams.php @@ -5,8 +5,8 @@ namespace Scrapegraphai\Crawl; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; -use Scrapegraphai\Core\Concerns\Params; +use Scrapegraphai\Core\Concerns\SdkModel; +use Scrapegraphai\Core\Concerns\SdkParams; use Scrapegraphai\Core\Contracts\BaseModel; use Scrapegraphai\Crawl\CrawlStartParams\Rules; @@ -14,23 +14,11 @@ * Initiate comprehensive website crawling with sitemap support. * Supports both AI extraction mode and markdown conversion mode. * Returns a task ID for async processing. - * - * @phpstan-type start_params = array{ - * url: string, - * depth?: int, - * extractionMode?: bool, - * maxPages?: int, - * prompt?: string|null, - * renderHeavyJs?: bool, - * rules?: Rules, - * schema?: mixed, - * sitemap?: bool, - * } */ final class CrawlStartParams implements BaseModel { - use Model; - use Params; + use SdkModel; + use SdkParams; /** * Starting URL for crawling. @@ -59,7 +47,7 @@ final class CrawlStartParams implements BaseModel /** * Extraction prompt (required if extraction_mode is true). */ - #[Api(optional: true)] + #[Api(nullable: true, optional: true)] public ?string $prompt; /** @@ -74,7 +62,7 @@ final class CrawlStartParams implements BaseModel /** * Output schema for extraction. */ - #[Api(optional: true)] + #[Api(nullable: true, optional: true)] public mixed $schema; /** @@ -83,6 +71,20 @@ final class CrawlStartParams implements BaseModel #[Api(optional: true)] public ?bool $sitemap; + /** + * `new CrawlStartParams()` is missing required properties by the API. + * + * To enforce required parameters use + * ``` + * CrawlStartParams::with(url: ...) + * ``` + * + * Otherwise ensure the following setters are called + * + * ``` + * (new CrawlStartParams)->withURL(...) + * ``` + */ public function __construct() { self::introspect(); @@ -94,7 +96,7 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. */ - public static function from( + public static function with( string $url, ?int $depth = null, ?bool $extractionMode = null, @@ -124,87 +126,96 @@ public static function from( /** * Starting URL for crawling. */ - public function setURL(string $url): self + public function withURL(string $url): self { - $this->url = $url; + $obj = clone $this; + $obj->url = $url; - return $this; + return $obj; } /** * Maximum crawl depth from starting URL. */ - public function setDepth(int $depth): self + public function withDepth(int $depth): self { - $this->depth = $depth; + $obj = clone $this; + $obj->depth = $depth; - return $this; + return $obj; } /** * Use AI extraction (true) or markdown conversion (false). */ - public function setExtractionMode(bool $extractionMode): self + public function withExtractionMode(bool $extractionMode): self { - $this->extractionMode = $extractionMode; + $obj = clone $this; + $obj->extractionMode = $extractionMode; - return $this; + return $obj; } /** * Maximum number of pages to crawl. */ - public function setMaxPages(int $maxPages): self + public function withMaxPages(int $maxPages): self { - $this->maxPages = $maxPages; + $obj = clone $this; + $obj->maxPages = $maxPages; - return $this; + return $obj; } /** * Extraction prompt (required if extraction_mode is true). */ - public function setPrompt(?string $prompt): self + public function withPrompt(?string $prompt): self { - $this->prompt = $prompt; + $obj = clone $this; + $obj->prompt = $prompt; - return $this; + return $obj; } /** * Enable heavy JavaScript rendering. */ - public function setRenderHeavyJs(bool $renderHeavyJs): self + public function withRenderHeavyJs(bool $renderHeavyJs): self { - $this->renderHeavyJs = $renderHeavyJs; + $obj = clone $this; + $obj->renderHeavyJs = $renderHeavyJs; - return $this; + return $obj; } - public function setRules(Rules $rules): self + public function withRules(Rules $rules): self { - $this->rules = $rules; + $obj = clone $this; + $obj->rules = $rules; - return $this; + return $obj; } /** * Output schema for extraction. */ - public function setSchema(mixed $schema): self + public function withSchema(mixed $schema): self { - $this->schema = $schema; + $obj = clone $this; + $obj->schema = $schema; - return $this; + return $obj; } /** * Use sitemap for crawling. */ - public function setSitemap(bool $sitemap): self + public function withSitemap(bool $sitemap): self { - $this->sitemap = $sitemap; + $obj = clone $this; + $obj->sitemap = $sitemap; - return $this; + return $obj; } } diff --git a/src/Crawl/CrawlStartParams/Rules.php b/src/Crawl/CrawlStartParams/Rules.php index c352317..a73af47 100644 --- a/src/Crawl/CrawlStartParams/Rules.php +++ b/src/Crawl/CrawlStartParams/Rules.php @@ -5,23 +5,19 @@ namespace Scrapegraphai\Crawl\CrawlStartParams; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; +use Scrapegraphai\Core\Concerns\SdkModel; use Scrapegraphai\Core\Contracts\BaseModel; -use Scrapegraphai\Core\Conversion\ListOf; -/** - * @phpstan-type rules_alias = array{exclude?: list, sameDomain?: bool} - */ final class Rules implements BaseModel { - use Model; + use SdkModel; /** * URL patterns to exclude from crawling. * - * @var null|list $exclude + * @var list|null $exclude */ - #[Api(type: new ListOf('string'), optional: true)] + #[Api(list: 'string', optional: true)] public ?array $exclude; /** @@ -41,9 +37,9 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. * - * @param null|list $exclude + * @param list $exclude */ - public static function from( + public static function with( ?array $exclude = null, ?bool $sameDomain = null ): self { @@ -60,20 +56,22 @@ public static function from( * * @param list $exclude */ - public function setExclude(array $exclude): self + public function withExclude(array $exclude): self { - $this->exclude = $exclude; + $obj = clone $this; + $obj->exclude = $exclude; - return $this; + return $obj; } /** * Restrict crawling to same domain. */ - public function setSameDomain(bool $sameDomain): self + public function withSameDomain(bool $sameDomain): self { - $this->sameDomain = $sameDomain; + $obj = clone $this; + $obj->sameDomain = $sameDomain; - return $this; + return $obj; } } diff --git a/src/Errors/APIError.php b/src/Errors/APIError.php index 29ec839..de673ce 100644 --- a/src/Errors/APIError.php +++ b/src/Errors/APIError.php @@ -18,6 +18,6 @@ public function __construct( ?\Throwable $previous = null, string $message = '', ) { - parent::__construct(message: 'response: '.$message.PHP_EOL.'request: '.$request->getBody()->__toString(), previous: $previous); + parent::__construct(message: $message, previous: $previous); } } diff --git a/src/Errors/APIStatusError.php b/src/Errors/APIStatusError.php index 5de7126..e6ceead 100644 --- a/src/Errors/APIStatusError.php +++ b/src/Errors/APIStatusError.php @@ -4,7 +4,7 @@ use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use Scrapegraphai\Core\Util; +use Psr\Http\Message\StreamInterface; class APIStatusError extends APIError { @@ -14,7 +14,6 @@ class APIStatusError extends APIError public ?int $status; public function __construct( - public mixed $body, public RequestInterface $request, ResponseInterface $response, ?\Throwable $previous = null, @@ -22,15 +21,19 @@ public function __construct( ) { $this->response = $response; $this->status = $response->getStatusCode(); - $message |= json_encode( - ['status' => $this->status, 'body' => $body], - flags: Util::JSON_ENCODE_FLAGS, - ); - parent::__construct(request: $request, message: $message, previous: $previous); + + $summary = 'Status: '.$this->status.PHP_EOL + .'Response Body: '.self::fmtBody($response->getBody()).PHP_EOL + .'Request Body: '.self::fmtBody($request->getBody()).PHP_EOL; + + if ('' != $message) { + $summary .= $message.PHP_EOL.$summary; + } + + parent::__construct(request: $request, message: $summary, previous: $previous); } public static function from( - mixed $body, RequestInterface $request, ResponseInterface $response ): self { @@ -48,6 +51,11 @@ public static function from( default => APIStatusError::class }; - return new $cls(body: $body, request: $request, response: $response); + return new $cls(request: $request, response: $response); + } + + private static function fmtBody(StreamInterface $body): string + { + return json_encode(json_decode($body->__toString() ?: ''), JSON_PRETTY_PRINT) ?: ''; } } diff --git a/src/Errors/Error.php b/src/Errors/Error.php index d606576..2eb393d 100644 --- a/src/Errors/Error.php +++ b/src/Errors/Error.php @@ -9,6 +9,6 @@ class Error extends \Exception public function __construct(string $message, int $code = 0, ?\Throwable $previous = null) { - parent::__construct($this::DESC.' '.$message, $code, $previous); + parent::__construct($this::DESC.PHP_EOL.$message, $code, $previous); } } diff --git a/src/Feedback/FeedbackSubmitParams.php b/src/Feedback/FeedbackSubmitParams.php index f7d25ef..e7372b6 100644 --- a/src/Feedback/FeedbackSubmitParams.php +++ b/src/Feedback/FeedbackSubmitParams.php @@ -5,21 +5,17 @@ namespace Scrapegraphai\Feedback; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; -use Scrapegraphai\Core\Concerns\Params; +use Scrapegraphai\Core\Concerns\SdkModel; +use Scrapegraphai\Core\Concerns\SdkParams; use Scrapegraphai\Core\Contracts\BaseModel; /** * Submit feedback for a specific request. - * - * @phpstan-type submit_params = array{ - * rating: int, requestID: string, feedbackText?: string|null - * } */ final class FeedbackSubmitParams implements BaseModel { - use Model; - use Params; + use SdkModel; + use SdkParams; /** * Rating score. @@ -36,9 +32,23 @@ final class FeedbackSubmitParams implements BaseModel /** * Optional feedback comments. */ - #[Api('feedback_text', optional: true)] + #[Api('feedback_text', nullable: true, optional: true)] public ?string $feedbackText; + /** + * `new FeedbackSubmitParams()` is missing required properties by the API. + * + * To enforce required parameters use + * ``` + * FeedbackSubmitParams::with(rating: ..., requestID: ...) + * ``` + * + * Otherwise ensure the following setters are called + * + * ``` + * (new FeedbackSubmitParams)->withRating(...)->withRequestID(...) + * ``` + */ public function __construct() { self::introspect(); @@ -50,7 +60,7 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. */ - public static function from( + public static function with( int $rating, string $requestID, ?string $feedbackText = null @@ -68,30 +78,33 @@ public static function from( /** * Rating score. */ - public function setRating(int $rating): self + public function withRating(int $rating): self { - $this->rating = $rating; + $obj = clone $this; + $obj->rating = $rating; - return $this; + return $obj; } /** * Request to provide feedback for. */ - public function setRequestID(string $requestID): self + public function withRequestID(string $requestID): self { - $this->requestID = $requestID; + $obj = clone $this; + $obj->requestID = $requestID; - return $this; + return $obj; } /** * Optional feedback comments. */ - public function setFeedbackText(?string $feedbackText): self + public function withFeedbackText(?string $feedbackText): self { - $this->feedbackText = $feedbackText; + $obj = clone $this; + $obj->feedbackText = $feedbackText; - return $this; + return $obj; } } diff --git a/src/GenerateSchema/GenerateSchemaCreateParams.php b/src/GenerateSchema/GenerateSchemaCreateParams.php index ff0158c..eed8204 100644 --- a/src/GenerateSchema/GenerateSchemaCreateParams.php +++ b/src/GenerateSchema/GenerateSchemaCreateParams.php @@ -5,20 +5,18 @@ namespace Scrapegraphai\GenerateSchema; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; -use Scrapegraphai\Core\Concerns\Params; +use Scrapegraphai\Core\Concerns\SdkModel; +use Scrapegraphai\Core\Concerns\SdkParams; use Scrapegraphai\Core\Contracts\BaseModel; /** * Generate or modify JSON schemas based on natural language descriptions. * Can create new schemas or extend existing ones. - * - * @phpstan-type create_params = array{userPrompt: string, existingSchema?: mixed} */ final class GenerateSchemaCreateParams implements BaseModel { - use Model; - use Params; + use SdkModel; + use SdkParams; /** * Natural language description of desired schema. @@ -29,9 +27,23 @@ final class GenerateSchemaCreateParams implements BaseModel /** * Existing schema to modify or extend. */ - #[Api('existing_schema', optional: true)] + #[Api('existing_schema', nullable: true, optional: true)] public mixed $existingSchema; + /** + * `new GenerateSchemaCreateParams()` is missing required properties by the API. + * + * To enforce required parameters use + * ``` + * GenerateSchemaCreateParams::with(userPrompt: ...) + * ``` + * + * Otherwise ensure the following setters are called + * + * ``` + * (new GenerateSchemaCreateParams)->withUserPrompt(...) + * ``` + */ public function __construct() { self::introspect(); @@ -43,7 +55,7 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. */ - public static function from( + public static function with( string $userPrompt, mixed $existingSchema = null ): self { @@ -59,20 +71,22 @@ public static function from( /** * Natural language description of desired schema. */ - public function setUserPrompt(string $userPrompt): self + public function withUserPrompt(string $userPrompt): self { - $this->userPrompt = $userPrompt; + $obj = clone $this; + $obj->userPrompt = $userPrompt; - return $this; + return $obj; } /** * Existing schema to modify or extend. */ - public function setExistingSchema(mixed $existingSchema): self + public function withExistingSchema(mixed $existingSchema): self { - $this->existingSchema = $existingSchema; + $obj = clone $this; + $obj->existingSchema = $existingSchema; - return $this; + return $obj; } } diff --git a/src/Markdownify/CompletedMarkdownify.php b/src/Markdownify/CompletedMarkdownify.php index 3c535a8..ab99144 100644 --- a/src/Markdownify/CompletedMarkdownify.php +++ b/src/Markdownify/CompletedMarkdownify.php @@ -5,22 +5,13 @@ namespace Scrapegraphai\Markdownify; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; +use Scrapegraphai\Core\Concerns\SdkModel; use Scrapegraphai\Core\Contracts\BaseModel; use Scrapegraphai\Markdownify\CompletedMarkdownify\Status; -/** - * @phpstan-type completed_markdownify_alias = array{ - * error?: string, - * requestID?: string, - * result?: string|null, - * status?: Status::*, - * websiteURL?: string, - * } - */ final class CompletedMarkdownify implements BaseModel { - use Model; + use SdkModel; #[Api(optional: true)] public ?string $error; @@ -31,10 +22,10 @@ final class CompletedMarkdownify implements BaseModel /** * Markdown content. */ - #[Api(optional: true)] + #[Api(nullable: true, optional: true)] public ?string $result; - /** @var null|Status::* $status */ + /** @var Status::*|null $status */ #[Api(enum: Status::class, optional: true)] public ?string $status; @@ -52,9 +43,9 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. * - * @param null|Status::* $status + * @param Status::* $status */ - public static function from( + public static function with( ?string $error = null, ?string $requestID = null, ?string $result = null, @@ -72,44 +63,49 @@ public static function from( return $obj; } - public function setError(string $error): self + public function withError(string $error): self { - $this->error = $error; + $obj = clone $this; + $obj->error = $error; - return $this; + return $obj; } - public function setRequestID(string $requestID): self + public function withRequestID(string $requestID): self { - $this->requestID = $requestID; + $obj = clone $this; + $obj->requestID = $requestID; - return $this; + return $obj; } /** * Markdown content. */ - public function setResult(?string $result): self + public function withResult(?string $result): self { - $this->result = $result; + $obj = clone $this; + $obj->result = $result; - return $this; + return $obj; } /** * @param Status::* $status */ - public function setStatus(string $status): self + public function withStatus(string $status): self { - $this->status = $status; + $obj = clone $this; + $obj->status = $status; - return $this; + return $obj; } - public function setWebsiteURL(string $websiteURL): self + public function withWebsiteURL(string $websiteURL): self { - $this->websiteURL = $websiteURL; + $obj = clone $this; + $obj->websiteURL = $websiteURL; - return $this; + return $obj; } } diff --git a/src/Markdownify/CompletedMarkdownify/Status.php b/src/Markdownify/CompletedMarkdownify/Status.php index d6e8ce9..8087933 100644 --- a/src/Markdownify/CompletedMarkdownify/Status.php +++ b/src/Markdownify/CompletedMarkdownify/Status.php @@ -4,15 +4,12 @@ namespace Scrapegraphai\Markdownify\CompletedMarkdownify; -use Scrapegraphai\Core\Concerns\Enum; +use Scrapegraphai\Core\Concerns\SdkEnum; use Scrapegraphai\Core\Conversion\Contracts\ConverterSource; -/** - * @phpstan-type status_alias = Status::* - */ final class Status implements ConverterSource { - use Enum; + use SdkEnum; public const QUEUED = 'queued'; diff --git a/src/Markdownify/MarkdownifyConvertParams.php b/src/Markdownify/MarkdownifyConvertParams.php index 74eec44..9699ef2 100644 --- a/src/Markdownify/MarkdownifyConvertParams.php +++ b/src/Markdownify/MarkdownifyConvertParams.php @@ -5,23 +5,17 @@ namespace Scrapegraphai\Markdownify; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; -use Scrapegraphai\Core\Concerns\Params; +use Scrapegraphai\Core\Concerns\SdkModel; +use Scrapegraphai\Core\Concerns\SdkParams; use Scrapegraphai\Core\Contracts\BaseModel; -use Scrapegraphai\Core\Conversion\ListOf; -use Scrapegraphai\Core\Conversion\MapOf; /** * Convert web page content to clean Markdown format. - * - * @phpstan-type convert_params = array{ - * websiteURL: string, headers?: array, steps?: list - * } */ final class MarkdownifyConvertParams implements BaseModel { - use Model; - use Params; + use SdkModel; + use SdkParams; /** * URL to convert to markdown. @@ -29,18 +23,32 @@ final class MarkdownifyConvertParams implements BaseModel #[Api('website_url')] public string $websiteURL; - /** @var null|array $headers */ - #[Api(type: new MapOf('string'), optional: true)] + /** @var array|null $headers */ + #[Api(map: 'string', optional: true)] public ?array $headers; /** * Interaction steps before conversion. * - * @var null|list $steps + * @var list|null $steps */ - #[Api(type: new ListOf('string'), optional: true)] + #[Api(list: 'string', optional: true)] public ?array $steps; + /** + * `new MarkdownifyConvertParams()` is missing required properties by the API. + * + * To enforce required parameters use + * ``` + * MarkdownifyConvertParams::with(websiteURL: ...) + * ``` + * + * Otherwise ensure the following setters are called + * + * ``` + * (new MarkdownifyConvertParams)->withWebsiteURL(...) + * ``` + */ public function __construct() { self::introspect(); @@ -52,10 +60,10 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. * - * @param null|array $headers - * @param null|list $steps + * @param array $headers + * @param list $steps */ - public static function from( + public static function with( string $websiteURL, ?array $headers = null, ?array $steps = null @@ -73,21 +81,23 @@ public static function from( /** * URL to convert to markdown. */ - public function setWebsiteURL(string $websiteURL): self + public function withWebsiteURL(string $websiteURL): self { - $this->websiteURL = $websiteURL; + $obj = clone $this; + $obj->websiteURL = $websiteURL; - return $this; + return $obj; } /** * @param array $headers */ - public function setHeaders(array $headers): self + public function withHeaders(array $headers): self { - $this->headers = $headers; + $obj = clone $this; + $obj->headers = $headers; - return $this; + return $obj; } /** @@ -95,10 +105,11 @@ public function setHeaders(array $headers): self * * @param list $steps */ - public function setSteps(array $steps): self + public function withSteps(array $steps): self { - $this->steps = $steps; + $obj = clone $this; + $obj->steps = $steps; - return $this; + return $obj; } } diff --git a/src/RequestOptions.php b/src/RequestOptions.php index 801bed6..2a541ce 100644 --- a/src/RequestOptions.php +++ b/src/RequestOptions.php @@ -55,13 +55,13 @@ public function __serialize(): array /** * @param array{ - * timeout?: null|float, - * maxRetries?: null|int, - * initialRetryDelay?: null|float, - * maxRetryDelay?: null|float, - * extraHeaders?: null|list, - * extraQueryParams?: null|list, - * extraBodyParams?: null|list, + * timeout?: float|null, + * maxRetries?: int|null, + * initialRetryDelay?: float|null, + * maxRetryDelay?: float|null, + * extraHeaders?: list|null, + * extraQueryParams?: list|null, + * extraBodyParams?: list|null, * } $data */ public function __unserialize(array $data): void @@ -88,17 +88,17 @@ public function __unserialize(array $data): void } /** - * @param null|array{ - * timeout?: null|float, - * maxRetries?: null|int, - * initialRetryDelay?: null|float, - * maxRetryDelay?: null|float, - * extraHeaders?: null|list, - * extraQueryParams?: null|list, - * extraBodyParams?: null|list, - * }|RequestOptions $options + * @param array{ + * timeout?: float|null, + * maxRetries?: int|null, + * initialRetryDelay?: float|null, + * maxRetryDelay?: float|null, + * extraHeaders?: list|null, + * extraQueryParams?: list|null, + * extraBodyParams?: list|null, + * }|RequestOptions|null $options */ - public static function parse(null|array|RequestOptions $options): self + public static function parse(array|RequestOptions|null $options): self { if (is_null($options)) { return new self; diff --git a/src/Responses/Crawl/CrawlGetResultsResponse.php b/src/Responses/Crawl/CrawlGetResultsResponse.php index 6c6f4f2..6efb80d 100644 --- a/src/Responses/Crawl/CrawlGetResultsResponse.php +++ b/src/Responses/Crawl/CrawlGetResultsResponse.php @@ -5,32 +5,24 @@ namespace Scrapegraphai\Responses\Crawl; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; +use Scrapegraphai\Core\Concerns\SdkModel; use Scrapegraphai\Core\Contracts\BaseModel; use Scrapegraphai\Responses\Crawl\CrawlGetResultsResponse\Result; use Scrapegraphai\Responses\Crawl\CrawlGetResultsResponse\Status; -/** - * @phpstan-type crawl_get_results_response_alias = array{ - * result?: mixed|string, - * status?: Status::*, - * taskID?: string, - * traceback?: string|null, - * } - */ final class CrawlGetResultsResponse implements BaseModel { - use Model; + use SdkModel; /** * Successful crawl results. * - * @var null|mixed|string $result + * @var mixed|string|null $result */ #[Api(union: Result::class, optional: true)] public mixed $result; - /** @var null|Status::* $status */ + /** @var Status::*|null $status */ #[Api(enum: Status::class, optional: true)] public ?string $status; @@ -40,7 +32,7 @@ final class CrawlGetResultsResponse implements BaseModel /** * Error traceback for failed tasks. */ - #[Api(optional: true)] + #[Api(nullable: true, optional: true)] public ?string $traceback; public function __construct() @@ -54,10 +46,10 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. * - * @param null|mixed|string $result - * @param null|Status::* $status + * @param mixed|string $result + * @param Status::* $status */ - public static function from( + public static function with( mixed $result = null, ?string $status = null, ?string $taskID = null, @@ -78,37 +70,41 @@ public static function from( * * @param mixed|string $result */ - public function setResult(mixed $result): self + public function withResult(mixed $result): self { - $this->result = $result; + $obj = clone $this; + $obj->result = $result; - return $this; + return $obj; } /** * @param Status::* $status */ - public function setStatus(string $status): self + public function withStatus(string $status): self { - $this->status = $status; + $obj = clone $this; + $obj->status = $status; - return $this; + return $obj; } - public function setTaskID(string $taskID): self + public function withTaskID(string $taskID): self { - $this->taskID = $taskID; + $obj = clone $this; + $obj->taskID = $taskID; - return $this; + return $obj; } /** * Error traceback for failed tasks. */ - public function setTraceback(?string $traceback): self + public function withTraceback(?string $traceback): self { - $this->traceback = $traceback; + $obj = clone $this; + $obj->traceback = $traceback; - return $this; + return $obj; } } diff --git a/src/Responses/Crawl/CrawlGetResultsResponse/Result.php b/src/Responses/Crawl/CrawlGetResultsResponse/Result.php index 0982820..4c36957 100644 --- a/src/Responses/Crawl/CrawlGetResultsResponse/Result.php +++ b/src/Responses/Crawl/CrawlGetResultsResponse/Result.php @@ -4,22 +4,20 @@ namespace Scrapegraphai\Responses\Crawl\CrawlGetResultsResponse; -use Scrapegraphai\Core\Concerns\Union; +use Scrapegraphai\Core\Concerns\SdkUnion; use Scrapegraphai\Core\Conversion\Contracts\Converter; use Scrapegraphai\Core\Conversion\Contracts\ConverterSource; /** * Successful crawl results. - * - * @phpstan-type result_alias = mixed|string */ final class Result implements ConverterSource { - use Union; + use SdkUnion; /** - * @return array|list + * @return list|array */ public static function variants(): array { diff --git a/src/Responses/Crawl/CrawlGetResultsResponse/Status.php b/src/Responses/Crawl/CrawlGetResultsResponse/Status.php index 17b18ac..02e3650 100644 --- a/src/Responses/Crawl/CrawlGetResultsResponse/Status.php +++ b/src/Responses/Crawl/CrawlGetResultsResponse/Status.php @@ -4,15 +4,12 @@ namespace Scrapegraphai\Responses\Crawl\CrawlGetResultsResponse; -use Scrapegraphai\Core\Concerns\Enum; +use Scrapegraphai\Core\Concerns\SdkEnum; use Scrapegraphai\Core\Conversion\Contracts\ConverterSource; -/** - * @phpstan-type status_alias = Status::* - */ final class Status implements ConverterSource { - use Enum; + use SdkEnum; public const PENDING = 'PENDING'; diff --git a/src/Responses/Crawl/CrawlStartResponse.php b/src/Responses/Crawl/CrawlStartResponse.php index 74277a9..94e64e4 100644 --- a/src/Responses/Crawl/CrawlStartResponse.php +++ b/src/Responses/Crawl/CrawlStartResponse.php @@ -5,15 +5,12 @@ namespace Scrapegraphai\Responses\Crawl; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; +use Scrapegraphai\Core\Concerns\SdkModel; use Scrapegraphai\Core\Contracts\BaseModel; -/** - * @phpstan-type crawl_start_response_alias = array{taskID?: string} - */ final class CrawlStartResponse implements BaseModel { - use Model; + use SdkModel; /** * Celery task identifier. @@ -32,7 +29,7 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. */ - public static function from(?string $taskID = null): self + public static function with(?string $taskID = null): self { $obj = new self; @@ -44,10 +41,11 @@ public static function from(?string $taskID = null): self /** * Celery task identifier. */ - public function setTaskID(string $taskID): self + public function withTaskID(string $taskID): self { - $this->taskID = $taskID; + $obj = clone $this; + $obj->taskID = $taskID; - return $this; + return $obj; } } diff --git a/src/Responses/Credits/CreditGetResponse.php b/src/Responses/Credits/CreditGetResponse.php index 6e388c8..00e0c60 100644 --- a/src/Responses/Credits/CreditGetResponse.php +++ b/src/Responses/Credits/CreditGetResponse.php @@ -5,17 +5,12 @@ namespace Scrapegraphai\Responses\Credits; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; +use Scrapegraphai\Core\Concerns\SdkModel; use Scrapegraphai\Core\Contracts\BaseModel; -/** - * @phpstan-type credit_get_response_alias = array{ - * remainingCredits?: int, totalCreditsUsed?: int - * } - */ final class CreditGetResponse implements BaseModel { - use Model; + use SdkModel; /** * Number of credits remaining. @@ -40,7 +35,7 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. */ - public static function from( + public static function with( ?int $remainingCredits = null, ?int $totalCreditsUsed = null ): self { @@ -55,20 +50,22 @@ public static function from( /** * Number of credits remaining. */ - public function setRemainingCredits(int $remainingCredits): self + public function withRemainingCredits(int $remainingCredits): self { - $this->remainingCredits = $remainingCredits; + $obj = clone $this; + $obj->remainingCredits = $remainingCredits; - return $this; + return $obj; } /** * Total credits consumed. */ - public function setTotalCreditsUsed(int $totalCreditsUsed): self + public function withTotalCreditsUsed(int $totalCreditsUsed): self { - $this->totalCreditsUsed = $totalCreditsUsed; + $obj = clone $this; + $obj->totalCreditsUsed = $totalCreditsUsed; - return $this; + return $obj; } } diff --git a/src/Responses/Feedback/FeedbackSubmitResponse.php b/src/Responses/Feedback/FeedbackSubmitResponse.php index d7e6791..dc71c86 100644 --- a/src/Responses/Feedback/FeedbackSubmitResponse.php +++ b/src/Responses/Feedback/FeedbackSubmitResponse.php @@ -5,20 +5,12 @@ namespace Scrapegraphai\Responses\Feedback; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; +use Scrapegraphai\Core\Concerns\SdkModel; use Scrapegraphai\Core\Contracts\BaseModel; -/** - * @phpstan-type feedback_submit_response_alias = array{ - * feedbackID?: string, - * feedbackTimestamp?: \DateTimeInterface, - * message?: string, - * requestID?: string, - * } - */ final class FeedbackSubmitResponse implements BaseModel { - use Model; + use SdkModel; #[Api('feedback_id', optional: true)] public ?string $feedbackID; @@ -43,7 +35,7 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. */ - public static function from( + public static function with( ?string $feedbackID = null, ?\DateTimeInterface $feedbackTimestamp = null, ?string $message = null, @@ -59,32 +51,36 @@ public static function from( return $obj; } - public function setFeedbackID(string $feedbackID): self + public function withFeedbackID(string $feedbackID): self { - $this->feedbackID = $feedbackID; + $obj = clone $this; + $obj->feedbackID = $feedbackID; - return $this; + return $obj; } - public function setFeedbackTimestamp( + public function withFeedbackTimestamp( \DateTimeInterface $feedbackTimestamp ): self { - $this->feedbackTimestamp = $feedbackTimestamp; + $obj = clone $this; + $obj->feedbackTimestamp = $feedbackTimestamp; - return $this; + return $obj; } - public function setMessage(string $message): self + public function withMessage(string $message): self { - $this->message = $message; + $obj = clone $this; + $obj->message = $message; - return $this; + return $obj; } - public function setRequestID(string $requestID): self + public function withRequestID(string $requestID): self { - $this->requestID = $requestID; + $obj = clone $this; + $obj->requestID = $requestID; - return $this; + return $obj; } } diff --git a/src/Responses/GenerateSchema/GenerateSchemaGetResponse.php b/src/Responses/GenerateSchema/GenerateSchemaGetResponse.php index 9606e48..100b707 100644 --- a/src/Responses/GenerateSchema/GenerateSchemaGetResponse.php +++ b/src/Responses/GenerateSchema/GenerateSchemaGetResponse.php @@ -4,22 +4,19 @@ namespace Scrapegraphai\Responses\GenerateSchema; -use Scrapegraphai\Core\Concerns\Union; +use Scrapegraphai\Core\Concerns\SdkUnion; use Scrapegraphai\Core\Conversion\Contracts\Converter; use Scrapegraphai\Core\Conversion\Contracts\ConverterSource; use Scrapegraphai\Responses\GenerateSchema\GenerateSchemaGetResponse\CompletedSchemaGenerationResponse; use Scrapegraphai\Responses\GenerateSchema\GenerateSchemaGetResponse\FailedSchemaGenerationResponse; -/** - * @phpstan-type generate_schema_get_response_alias = CompletedSchemaGenerationResponse|FailedSchemaGenerationResponse - */ final class GenerateSchemaGetResponse implements ConverterSource { - use Union; + use SdkUnion; /** - * @return array|list + * @return list|array */ public static function variants(): array { diff --git a/src/Responses/GenerateSchema/GenerateSchemaGetResponse/CompletedSchemaGenerationResponse.php b/src/Responses/GenerateSchema/GenerateSchemaGetResponse/CompletedSchemaGenerationResponse.php index c1cd234..d788ecc 100644 --- a/src/Responses/GenerateSchema/GenerateSchemaGetResponse/CompletedSchemaGenerationResponse.php +++ b/src/Responses/GenerateSchema/GenerateSchemaGetResponse/CompletedSchemaGenerationResponse.php @@ -5,25 +5,15 @@ namespace Scrapegraphai\Responses\GenerateSchema\GenerateSchemaGetResponse; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; +use Scrapegraphai\Core\Concerns\SdkModel; use Scrapegraphai\Core\Contracts\BaseModel; use Scrapegraphai\Responses\GenerateSchema\GenerateSchemaGetResponse\CompletedSchemaGenerationResponse\Status; -/** - * @phpstan-type completed_schema_generation_response_alias = array{ - * error?: string|null, - * generatedSchema?: mixed, - * refinedPrompt?: string, - * requestID?: string, - * status?: Status::*, - * userPrompt?: string, - * } - */ final class CompletedSchemaGenerationResponse implements BaseModel { - use Model; + use SdkModel; - #[Api(optional: true)] + #[Api(nullable: true, optional: true)] public ?string $error; #[Api('generated_schema', optional: true)] @@ -35,7 +25,7 @@ final class CompletedSchemaGenerationResponse implements BaseModel #[Api('request_id', optional: true)] public ?string $requestID; - /** @var null|Status::* $status */ + /** @var Status::*|null $status */ #[Api(enum: Status::class, optional: true)] public ?string $status; @@ -53,9 +43,9 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. * - * @param null|Status::* $status + * @param Status::* $status */ - public static function from( + public static function with( ?string $error = null, mixed $generatedSchema = null, ?string $refinedPrompt = null, @@ -75,48 +65,54 @@ public static function from( return $obj; } - public function setError(?string $error): self + public function withError(?string $error): self { - $this->error = $error; + $obj = clone $this; + $obj->error = $error; - return $this; + return $obj; } - public function setGeneratedSchema(mixed $generatedSchema): self + public function withGeneratedSchema(mixed $generatedSchema): self { - $this->generatedSchema = $generatedSchema; + $obj = clone $this; + $obj->generatedSchema = $generatedSchema; - return $this; + return $obj; } - public function setRefinedPrompt(string $refinedPrompt): self + public function withRefinedPrompt(string $refinedPrompt): self { - $this->refinedPrompt = $refinedPrompt; + $obj = clone $this; + $obj->refinedPrompt = $refinedPrompt; - return $this; + return $obj; } - public function setRequestID(string $requestID): self + public function withRequestID(string $requestID): self { - $this->requestID = $requestID; + $obj = clone $this; + $obj->requestID = $requestID; - return $this; + return $obj; } /** * @param Status::* $status */ - public function setStatus(string $status): self + public function withStatus(string $status): self { - $this->status = $status; + $obj = clone $this; + $obj->status = $status; - return $this; + return $obj; } - public function setUserPrompt(string $userPrompt): self + public function withUserPrompt(string $userPrompt): self { - $this->userPrompt = $userPrompt; + $obj = clone $this; + $obj->userPrompt = $userPrompt; - return $this; + return $obj; } } diff --git a/src/Responses/GenerateSchema/GenerateSchemaGetResponse/CompletedSchemaGenerationResponse/Status.php b/src/Responses/GenerateSchema/GenerateSchemaGetResponse/CompletedSchemaGenerationResponse/Status.php index 6c3f821..e6a3e96 100644 --- a/src/Responses/GenerateSchema/GenerateSchemaGetResponse/CompletedSchemaGenerationResponse/Status.php +++ b/src/Responses/GenerateSchema/GenerateSchemaGetResponse/CompletedSchemaGenerationResponse/Status.php @@ -4,15 +4,12 @@ namespace Scrapegraphai\Responses\GenerateSchema\GenerateSchemaGetResponse\CompletedSchemaGenerationResponse; -use Scrapegraphai\Core\Concerns\Enum; +use Scrapegraphai\Core\Concerns\SdkEnum; use Scrapegraphai\Core\Conversion\Contracts\ConverterSource; -/** - * @phpstan-type status_alias = Status::* - */ final class Status implements ConverterSource { - use Enum; + use SdkEnum; public const COMPLETED = 'completed'; } diff --git a/src/Responses/GenerateSchema/GenerateSchemaGetResponse/FailedSchemaGenerationResponse.php b/src/Responses/GenerateSchema/GenerateSchemaGetResponse/FailedSchemaGenerationResponse.php index 9aec21d..2703192 100644 --- a/src/Responses/GenerateSchema/GenerateSchemaGetResponse/FailedSchemaGenerationResponse.php +++ b/src/Responses/GenerateSchema/GenerateSchemaGetResponse/FailedSchemaGenerationResponse.php @@ -5,37 +5,27 @@ namespace Scrapegraphai\Responses\GenerateSchema\GenerateSchemaGetResponse; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; +use Scrapegraphai\Core\Concerns\SdkModel; use Scrapegraphai\Core\Contracts\BaseModel; use Scrapegraphai\Responses\GenerateSchema\GenerateSchemaGetResponse\FailedSchemaGenerationResponse\Status; -/** - * @phpstan-type failed_schema_generation_response_alias = array{ - * error?: string, - * generatedSchema?: mixed, - * refinedPrompt?: string|null, - * requestID?: string, - * status?: Status::*, - * userPrompt?: string, - * } - */ final class FailedSchemaGenerationResponse implements BaseModel { - use Model; + use SdkModel; #[Api(optional: true)] public ?string $error; - #[Api('generated_schema', optional: true)] + #[Api('generated_schema', nullable: true, optional: true)] public mixed $generatedSchema; - #[Api('refined_prompt', optional: true)] + #[Api('refined_prompt', nullable: true, optional: true)] public ?string $refinedPrompt; #[Api('request_id', optional: true)] public ?string $requestID; - /** @var null|Status::* $status */ + /** @var Status::*|null $status */ #[Api(enum: Status::class, optional: true)] public ?string $status; @@ -53,9 +43,9 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. * - * @param null|Status::* $status + * @param Status::* $status */ - public static function from( + public static function with( ?string $error = null, mixed $generatedSchema = null, ?string $refinedPrompt = null, @@ -75,48 +65,54 @@ public static function from( return $obj; } - public function setError(string $error): self + public function withError(string $error): self { - $this->error = $error; + $obj = clone $this; + $obj->error = $error; - return $this; + return $obj; } - public function setGeneratedSchema(mixed $generatedSchema): self + public function withGeneratedSchema(mixed $generatedSchema): self { - $this->generatedSchema = $generatedSchema; + $obj = clone $this; + $obj->generatedSchema = $generatedSchema; - return $this; + return $obj; } - public function setRefinedPrompt(?string $refinedPrompt): self + public function withRefinedPrompt(?string $refinedPrompt): self { - $this->refinedPrompt = $refinedPrompt; + $obj = clone $this; + $obj->refinedPrompt = $refinedPrompt; - return $this; + return $obj; } - public function setRequestID(string $requestID): self + public function withRequestID(string $requestID): self { - $this->requestID = $requestID; + $obj = clone $this; + $obj->requestID = $requestID; - return $this; + return $obj; } /** * @param Status::* $status */ - public function setStatus(string $status): self + public function withStatus(string $status): self { - $this->status = $status; + $obj = clone $this; + $obj->status = $status; - return $this; + return $obj; } - public function setUserPrompt(string $userPrompt): self + public function withUserPrompt(string $userPrompt): self { - $this->userPrompt = $userPrompt; + $obj = clone $this; + $obj->userPrompt = $userPrompt; - return $this; + return $obj; } } diff --git a/src/Responses/GenerateSchema/GenerateSchemaGetResponse/FailedSchemaGenerationResponse/Status.php b/src/Responses/GenerateSchema/GenerateSchemaGetResponse/FailedSchemaGenerationResponse/Status.php index 9315df6..f67b258 100644 --- a/src/Responses/GenerateSchema/GenerateSchemaGetResponse/FailedSchemaGenerationResponse/Status.php +++ b/src/Responses/GenerateSchema/GenerateSchemaGetResponse/FailedSchemaGenerationResponse/Status.php @@ -4,15 +4,12 @@ namespace Scrapegraphai\Responses\GenerateSchema\GenerateSchemaGetResponse\FailedSchemaGenerationResponse; -use Scrapegraphai\Core\Concerns\Enum; +use Scrapegraphai\Core\Concerns\SdkEnum; use Scrapegraphai\Core\Conversion\Contracts\ConverterSource; -/** - * @phpstan-type status_alias = Status::* - */ final class Status implements ConverterSource { - use Enum; + use SdkEnum; public const FAILED = 'failed'; } diff --git a/src/Responses/GenerateSchema/GenerateSchemaNewResponse.php b/src/Responses/GenerateSchema/GenerateSchemaNewResponse.php index 6e30b10..8dbe968 100644 --- a/src/Responses/GenerateSchema/GenerateSchemaNewResponse.php +++ b/src/Responses/GenerateSchema/GenerateSchemaNewResponse.php @@ -5,25 +5,15 @@ namespace Scrapegraphai\Responses\GenerateSchema; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; +use Scrapegraphai\Core\Concerns\SdkModel; use Scrapegraphai\Core\Contracts\BaseModel; use Scrapegraphai\Responses\GenerateSchema\GenerateSchemaNewResponse\Status; -/** - * @phpstan-type generate_schema_new_response_alias = array{ - * error?: string|null, - * generatedSchema?: mixed, - * refinedPrompt?: string, - * requestID?: string, - * status?: Status::*, - * userPrompt?: string, - * } - */ final class GenerateSchemaNewResponse implements BaseModel { - use Model; + use SdkModel; - #[Api(optional: true)] + #[Api(nullable: true, optional: true)] public ?string $error; /** @@ -41,7 +31,7 @@ final class GenerateSchemaNewResponse implements BaseModel #[Api('request_id', optional: true)] public ?string $requestID; - /** @var null|Status::* $status */ + /** @var Status::*|null $status */ #[Api(enum: Status::class, optional: true)] public ?string $status; @@ -59,9 +49,9 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. * - * @param null|Status::* $status + * @param Status::* $status */ - public static function from( + public static function with( ?string $error = null, mixed $generatedSchema = null, ?string $refinedPrompt = null, @@ -81,54 +71,60 @@ public static function from( return $obj; } - public function setError(?string $error): self + public function withError(?string $error): self { - $this->error = $error; + $obj = clone $this; + $obj->error = $error; - return $this; + return $obj; } /** * Generated JSON schema. */ - public function setGeneratedSchema(mixed $generatedSchema): self + public function withGeneratedSchema(mixed $generatedSchema): self { - $this->generatedSchema = $generatedSchema; + $obj = clone $this; + $obj->generatedSchema = $generatedSchema; - return $this; + return $obj; } /** * Enhanced search prompt generated from user input. */ - public function setRefinedPrompt(string $refinedPrompt): self + public function withRefinedPrompt(string $refinedPrompt): self { - $this->refinedPrompt = $refinedPrompt; + $obj = clone $this; + $obj->refinedPrompt = $refinedPrompt; - return $this; + return $obj; } - public function setRequestID(string $requestID): self + public function withRequestID(string $requestID): self { - $this->requestID = $requestID; + $obj = clone $this; + $obj->requestID = $requestID; - return $this; + return $obj; } /** * @param Status::* $status */ - public function setStatus(string $status): self + public function withStatus(string $status): self { - $this->status = $status; + $obj = clone $this; + $obj->status = $status; - return $this; + return $obj; } - public function setUserPrompt(string $userPrompt): self + public function withUserPrompt(string $userPrompt): self { - $this->userPrompt = $userPrompt; + $obj = clone $this; + $obj->userPrompt = $userPrompt; - return $this; + return $obj; } } diff --git a/src/Responses/GenerateSchema/GenerateSchemaNewResponse/Status.php b/src/Responses/GenerateSchema/GenerateSchemaNewResponse/Status.php index 838b394..eecd235 100644 --- a/src/Responses/GenerateSchema/GenerateSchemaNewResponse/Status.php +++ b/src/Responses/GenerateSchema/GenerateSchemaNewResponse/Status.php @@ -4,15 +4,12 @@ namespace Scrapegraphai\Responses\GenerateSchema\GenerateSchemaNewResponse; -use Scrapegraphai\Core\Concerns\Enum; +use Scrapegraphai\Core\Concerns\SdkEnum; use Scrapegraphai\Core\Conversion\Contracts\ConverterSource; -/** - * @phpstan-type status_alias = Status::* - */ final class Status implements ConverterSource { - use Enum; + use SdkEnum; public const COMPLETED = 'completed'; } diff --git a/src/Responses/Healthz/HealthzCheckResponse.php b/src/Responses/Healthz/HealthzCheckResponse.php index 4439c13..4828008 100644 --- a/src/Responses/Healthz/HealthzCheckResponse.php +++ b/src/Responses/Healthz/HealthzCheckResponse.php @@ -5,21 +5,15 @@ namespace Scrapegraphai\Responses\Healthz; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; +use Scrapegraphai\Core\Concerns\SdkModel; use Scrapegraphai\Core\Contracts\BaseModel; -use Scrapegraphai\Core\Conversion\MapOf; -/** - * @phpstan-type healthz_check_response_alias = array{ - * services?: array, status?: string - * } - */ final class HealthzCheckResponse implements BaseModel { - use Model; + use SdkModel; - /** @var null|array $services */ - #[Api(type: new MapOf('string'), optional: true)] + /** @var array|null $services */ + #[Api(map: 'string', optional: true)] public ?array $services; #[Api(optional: true)] @@ -36,9 +30,9 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. * - * @param null|array $services + * @param array $services */ - public static function from( + public static function with( ?array $services = null, ?string $status = null ): self { @@ -53,17 +47,19 @@ public static function from( /** * @param array $services */ - public function setServices(array $services): self + public function withServices(array $services): self { - $this->services = $services; + $obj = clone $this; + $obj->services = $services; - return $this; + return $obj; } - public function setStatus(string $status): self + public function withStatus(string $status): self { - $this->status = $status; + $obj = clone $this; + $obj->status = $status; - return $this; + return $obj; } } diff --git a/src/Responses/Markdownify/MarkdownifyGetStatusResponse.php b/src/Responses/Markdownify/MarkdownifyGetStatusResponse.php index d5b9236..14061e8 100644 --- a/src/Responses/Markdownify/MarkdownifyGetStatusResponse.php +++ b/src/Responses/Markdownify/MarkdownifyGetStatusResponse.php @@ -4,22 +4,19 @@ namespace Scrapegraphai\Responses\Markdownify; -use Scrapegraphai\Core\Concerns\Union; +use Scrapegraphai\Core\Concerns\SdkUnion; use Scrapegraphai\Core\Conversion\Contracts\Converter; use Scrapegraphai\Core\Conversion\Contracts\ConverterSource; use Scrapegraphai\Markdownify\CompletedMarkdownify; use Scrapegraphai\Responses\Markdownify\MarkdownifyGetStatusResponse\FailedMarkdownifyResponse; -/** - * @phpstan-type markdownify_get_status_response_alias = CompletedMarkdownify|FailedMarkdownifyResponse - */ final class MarkdownifyGetStatusResponse implements ConverterSource { - use Union; + use SdkUnion; /** - * @return array|list + * @return list|array */ public static function variants(): array { diff --git a/src/Responses/Markdownify/MarkdownifyGetStatusResponse/FailedMarkdownifyResponse.php b/src/Responses/Markdownify/MarkdownifyGetStatusResponse/FailedMarkdownifyResponse.php index 11f2a2f..2a1a00e 100644 --- a/src/Responses/Markdownify/MarkdownifyGetStatusResponse/FailedMarkdownifyResponse.php +++ b/src/Responses/Markdownify/MarkdownifyGetStatusResponse/FailedMarkdownifyResponse.php @@ -5,22 +5,13 @@ namespace Scrapegraphai\Responses\Markdownify\MarkdownifyGetStatusResponse; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; +use Scrapegraphai\Core\Concerns\SdkModel; use Scrapegraphai\Core\Contracts\BaseModel; use Scrapegraphai\Responses\Markdownify\MarkdownifyGetStatusResponse\FailedMarkdownifyResponse\Status; -/** - * @phpstan-type failed_markdownify_response_alias = array{ - * error?: string, - * requestID?: string, - * result?: string|null, - * status?: Status::*, - * websiteURL?: string, - * } - */ final class FailedMarkdownifyResponse implements BaseModel { - use Model; + use SdkModel; #[Api(optional: true)] public ?string $error; @@ -28,10 +19,10 @@ final class FailedMarkdownifyResponse implements BaseModel #[Api('request_id', optional: true)] public ?string $requestID; - #[Api(optional: true)] + #[Api(nullable: true, optional: true)] public ?string $result; - /** @var null|Status::* $status */ + /** @var Status::*|null $status */ #[Api(enum: Status::class, optional: true)] public ?string $status; @@ -49,9 +40,9 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. * - * @param null|Status::* $status + * @param Status::* $status */ - public static function from( + public static function with( ?string $error = null, ?string $requestID = null, ?string $result = null, @@ -69,41 +60,46 @@ public static function from( return $obj; } - public function setError(string $error): self + public function withError(string $error): self { - $this->error = $error; + $obj = clone $this; + $obj->error = $error; - return $this; + return $obj; } - public function setRequestID(string $requestID): self + public function withRequestID(string $requestID): self { - $this->requestID = $requestID; + $obj = clone $this; + $obj->requestID = $requestID; - return $this; + return $obj; } - public function setResult(?string $result): self + public function withResult(?string $result): self { - $this->result = $result; + $obj = clone $this; + $obj->result = $result; - return $this; + return $obj; } /** * @param Status::* $status */ - public function setStatus(string $status): self + public function withStatus(string $status): self { - $this->status = $status; + $obj = clone $this; + $obj->status = $status; - return $this; + return $obj; } - public function setWebsiteURL(string $websiteURL): self + public function withWebsiteURL(string $websiteURL): self { - $this->websiteURL = $websiteURL; + $obj = clone $this; + $obj->websiteURL = $websiteURL; - return $this; + return $obj; } } diff --git a/src/Responses/Markdownify/MarkdownifyGetStatusResponse/FailedMarkdownifyResponse/Status.php b/src/Responses/Markdownify/MarkdownifyGetStatusResponse/FailedMarkdownifyResponse/Status.php index 7be697e..e173831 100644 --- a/src/Responses/Markdownify/MarkdownifyGetStatusResponse/FailedMarkdownifyResponse/Status.php +++ b/src/Responses/Markdownify/MarkdownifyGetStatusResponse/FailedMarkdownifyResponse/Status.php @@ -4,15 +4,12 @@ namespace Scrapegraphai\Responses\Markdownify\MarkdownifyGetStatusResponse\FailedMarkdownifyResponse; -use Scrapegraphai\Core\Concerns\Enum; +use Scrapegraphai\Core\Concerns\SdkEnum; use Scrapegraphai\Core\Conversion\Contracts\ConverterSource; -/** - * @phpstan-type status_alias = Status::* - */ final class Status implements ConverterSource { - use Enum; + use SdkEnum; public const FAILED = 'failed'; } diff --git a/src/Responses/Searchscraper/SearchscraperGetStatusResponse.php b/src/Responses/Searchscraper/SearchscraperGetStatusResponse.php index 7544142..67bf387 100644 --- a/src/Responses/Searchscraper/SearchscraperGetStatusResponse.php +++ b/src/Responses/Searchscraper/SearchscraperGetStatusResponse.php @@ -4,22 +4,19 @@ namespace Scrapegraphai\Responses\Searchscraper; -use Scrapegraphai\Core\Concerns\Union; +use Scrapegraphai\Core\Concerns\SdkUnion; use Scrapegraphai\Core\Conversion\Contracts\Converter; use Scrapegraphai\Core\Conversion\Contracts\ConverterSource; use Scrapegraphai\Responses\Searchscraper\SearchscraperGetStatusResponse\FailedSearchScraperResponse; use Scrapegraphai\Searchscraper\CompletedSearchScraper; -/** - * @phpstan-type searchscraper_get_status_response_alias = CompletedSearchScraper|FailedSearchScraperResponse - */ final class SearchscraperGetStatusResponse implements ConverterSource { - use Union; + use SdkUnion; /** - * @return array|list + * @return list|array */ public static function variants(): array { diff --git a/src/Responses/Searchscraper/SearchscraperGetStatusResponse/FailedSearchScraperResponse.php b/src/Responses/Searchscraper/SearchscraperGetStatusResponse/FailedSearchScraperResponse.php index a2f0ba1..31972dc 100644 --- a/src/Responses/Searchscraper/SearchscraperGetStatusResponse/FailedSearchScraperResponse.php +++ b/src/Responses/Searchscraper/SearchscraperGetStatusResponse/FailedSearchScraperResponse.php @@ -5,25 +5,13 @@ namespace Scrapegraphai\Responses\Searchscraper\SearchscraperGetStatusResponse; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; +use Scrapegraphai\Core\Concerns\SdkModel; use Scrapegraphai\Core\Contracts\BaseModel; -use Scrapegraphai\Core\Conversion\ListOf; use Scrapegraphai\Responses\Searchscraper\SearchscraperGetStatusResponse\FailedSearchScraperResponse\Status; -/** - * @phpstan-type failed_search_scraper_response_alias = array{ - * error?: string, - * numResults?: int, - * referenceURLs?: list, - * requestID?: string, - * result?: mixed, - * status?: Status::*, - * userPrompt?: string, - * } - */ final class FailedSearchScraperResponse implements BaseModel { - use Model; + use SdkModel; #[Api(optional: true)] public ?string $error; @@ -31,17 +19,17 @@ final class FailedSearchScraperResponse implements BaseModel #[Api('num_results', optional: true)] public ?int $numResults; - /** @var null|list $referenceURLs */ - #[Api('reference_urls', type: new ListOf('string'), optional: true)] + /** @var list|null $referenceURLs */ + #[Api('reference_urls', list: 'string', optional: true)] public ?array $referenceURLs; #[Api('request_id', optional: true)] public ?string $requestID; - #[Api(optional: true)] + #[Api(nullable: true, optional: true)] public mixed $result; - /** @var null|Status::* $status */ + /** @var Status::*|null $status */ #[Api(enum: Status::class, optional: true)] public ?string $status; @@ -59,10 +47,10 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. * - * @param null|list $referenceURLs - * @param null|Status::* $status + * @param list $referenceURLs + * @param Status::* $status */ - public static function from( + public static function with( ?string $error = null, ?int $numResults = null, ?array $referenceURLs = null, @@ -84,58 +72,65 @@ public static function from( return $obj; } - public function setError(string $error): self + public function withError(string $error): self { - $this->error = $error; + $obj = clone $this; + $obj->error = $error; - return $this; + return $obj; } - public function setNumResults(int $numResults): self + public function withNumResults(int $numResults): self { - $this->numResults = $numResults; + $obj = clone $this; + $obj->numResults = $numResults; - return $this; + return $obj; } /** * @param list $referenceURLs */ - public function setReferenceURLs(array $referenceURLs): self + public function withReferenceURLs(array $referenceURLs): self { - $this->referenceURLs = $referenceURLs; + $obj = clone $this; + $obj->referenceURLs = $referenceURLs; - return $this; + return $obj; } - public function setRequestID(string $requestID): self + public function withRequestID(string $requestID): self { - $this->requestID = $requestID; + $obj = clone $this; + $obj->requestID = $requestID; - return $this; + return $obj; } - public function setResult(mixed $result): self + public function withResult(mixed $result): self { - $this->result = $result; + $obj = clone $this; + $obj->result = $result; - return $this; + return $obj; } /** * @param Status::* $status */ - public function setStatus(string $status): self + public function withStatus(string $status): self { - $this->status = $status; + $obj = clone $this; + $obj->status = $status; - return $this; + return $obj; } - public function setUserPrompt(string $userPrompt): self + public function withUserPrompt(string $userPrompt): self { - $this->userPrompt = $userPrompt; + $obj = clone $this; + $obj->userPrompt = $userPrompt; - return $this; + return $obj; } } diff --git a/src/Responses/Searchscraper/SearchscraperGetStatusResponse/FailedSearchScraperResponse/Status.php b/src/Responses/Searchscraper/SearchscraperGetStatusResponse/FailedSearchScraperResponse/Status.php index 36824a3..3c15568 100644 --- a/src/Responses/Searchscraper/SearchscraperGetStatusResponse/FailedSearchScraperResponse/Status.php +++ b/src/Responses/Searchscraper/SearchscraperGetStatusResponse/FailedSearchScraperResponse/Status.php @@ -4,15 +4,12 @@ namespace Scrapegraphai\Responses\Searchscraper\SearchscraperGetStatusResponse\FailedSearchScraperResponse; -use Scrapegraphai\Core\Concerns\Enum; +use Scrapegraphai\Core\Concerns\SdkEnum; use Scrapegraphai\Core\Conversion\Contracts\ConverterSource; -/** - * @phpstan-type status_alias = Status::* - */ final class Status implements ConverterSource { - use Enum; + use SdkEnum; public const FAILED = 'failed'; } diff --git a/src/Responses/Smartscraper/SmartscraperGetResponse.php b/src/Responses/Smartscraper/SmartscraperGetResponse.php index 9e59886..5af25f8 100644 --- a/src/Responses/Smartscraper/SmartscraperGetResponse.php +++ b/src/Responses/Smartscraper/SmartscraperGetResponse.php @@ -4,22 +4,19 @@ namespace Scrapegraphai\Responses\Smartscraper; -use Scrapegraphai\Core\Concerns\Union; +use Scrapegraphai\Core\Concerns\SdkUnion; use Scrapegraphai\Core\Conversion\Contracts\Converter; use Scrapegraphai\Core\Conversion\Contracts\ConverterSource; use Scrapegraphai\Smartscraper\CompletedSmartscraper; use Scrapegraphai\Smartscraper\FailedSmartscraper; -/** - * @phpstan-type smartscraper_get_response_alias = CompletedSmartscraper|FailedSmartscraper - */ final class SmartscraperGetResponse implements ConverterSource { - use Union; + use SdkUnion; /** - * @return array|list + * @return list|array */ public static function variants(): array { diff --git a/src/Responses/Smartscraper/SmartscraperListResponse.php b/src/Responses/Smartscraper/SmartscraperListResponse.php index 3297bac..5e20795 100644 --- a/src/Responses/Smartscraper/SmartscraperListResponse.php +++ b/src/Responses/Smartscraper/SmartscraperListResponse.php @@ -4,22 +4,19 @@ namespace Scrapegraphai\Responses\Smartscraper; -use Scrapegraphai\Core\Concerns\Union; +use Scrapegraphai\Core\Concerns\SdkUnion; use Scrapegraphai\Core\Conversion\Contracts\Converter; use Scrapegraphai\Core\Conversion\Contracts\ConverterSource; use Scrapegraphai\Smartscraper\CompletedSmartscraper; use Scrapegraphai\Smartscraper\FailedSmartscraper; -/** - * @phpstan-type smartscraper_list_response_alias = CompletedSmartscraper|FailedSmartscraper - */ final class SmartscraperListResponse implements ConverterSource { - use Union; + use SdkUnion; /** - * @return array|list + * @return list|array */ public static function variants(): array { diff --git a/src/Responses/Validate/ValidateAPIKeyResponse.php b/src/Responses/Validate/ValidateAPIKeyResponse.php index bed9c37..bf40f3b 100644 --- a/src/Responses/Validate/ValidateAPIKeyResponse.php +++ b/src/Responses/Validate/ValidateAPIKeyResponse.php @@ -5,15 +5,12 @@ namespace Scrapegraphai\Responses\Validate; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; +use Scrapegraphai\Core\Concerns\SdkModel; use Scrapegraphai\Core\Contracts\BaseModel; -/** - * @phpstan-type validate_api_key_response_alias = array{email?: string} - */ final class ValidateAPIKeyResponse implements BaseModel { - use Model; + use SdkModel; #[Api(optional: true)] public ?string $email; @@ -29,7 +26,7 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. */ - public static function from(?string $email = null): self + public static function with(?string $email = null): self { $obj = new self; @@ -38,10 +35,11 @@ public static function from(?string $email = null): self return $obj; } - public function setEmail(string $email): self + public function withEmail(string $email): self { - $this->email = $email; + $obj = clone $this; + $obj->email = $email; - return $this; + return $obj; } } diff --git a/src/Searchscraper/CompletedSearchScraper.php b/src/Searchscraper/CompletedSearchScraper.php index b6fe395..701b23e 100644 --- a/src/Searchscraper/CompletedSearchScraper.php +++ b/src/Searchscraper/CompletedSearchScraper.php @@ -5,27 +5,15 @@ namespace Scrapegraphai\Searchscraper; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; +use Scrapegraphai\Core\Concerns\SdkModel; use Scrapegraphai\Core\Contracts\BaseModel; -use Scrapegraphai\Core\Conversion\ListOf; use Scrapegraphai\Searchscraper\CompletedSearchScraper\Status; -/** - * @phpstan-type completed_search_scraper_alias = array{ - * error?: string|null, - * numResults?: int, - * referenceURLs?: list, - * requestID?: string, - * result?: mixed, - * status?: Status::*, - * userPrompt?: string, - * } - */ final class CompletedSearchScraper implements BaseModel { - use Model; + use SdkModel; - #[Api(optional: true)] + #[Api(nullable: true, optional: true)] public ?string $error; #[Api('num_results', optional: true)] @@ -34,9 +22,9 @@ final class CompletedSearchScraper implements BaseModel /** * URLs of sources used. * - * @var null|list $referenceURLs + * @var list|null $referenceURLs */ - #[Api('reference_urls', type: new ListOf('string'), optional: true)] + #[Api('reference_urls', list: 'string', optional: true)] public ?array $referenceURLs; #[Api('request_id', optional: true)] @@ -48,7 +36,7 @@ final class CompletedSearchScraper implements BaseModel #[Api(optional: true)] public mixed $result; - /** @var null|Status::* $status */ + /** @var Status::*|null $status */ #[Api(enum: Status::class, optional: true)] public ?string $status; @@ -66,10 +54,10 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. * - * @param null|list $referenceURLs - * @param null|Status::* $status + * @param list $referenceURLs + * @param Status::* $status */ - public static function from( + public static function with( ?string $error = null, ?int $numResults = null, ?array $referenceURLs = null, @@ -91,18 +79,20 @@ public static function from( return $obj; } - public function setError(?string $error): self + public function withError(?string $error): self { - $this->error = $error; + $obj = clone $this; + $obj->error = $error; - return $this; + return $obj; } - public function setNumResults(int $numResults): self + public function withNumResults(int $numResults): self { - $this->numResults = $numResults; + $obj = clone $this; + $obj->numResults = $numResults; - return $this; + return $obj; } /** @@ -110,44 +100,49 @@ public function setNumResults(int $numResults): self * * @param list $referenceURLs */ - public function setReferenceURLs(array $referenceURLs): self + public function withReferenceURLs(array $referenceURLs): self { - $this->referenceURLs = $referenceURLs; + $obj = clone $this; + $obj->referenceURLs = $referenceURLs; - return $this; + return $obj; } - public function setRequestID(string $requestID): self + public function withRequestID(string $requestID): self { - $this->requestID = $requestID; + $obj = clone $this; + $obj->requestID = $requestID; - return $this; + return $obj; } /** * Merged results from all scraped websites. */ - public function setResult(mixed $result): self + public function withResult(mixed $result): self { - $this->result = $result; + $obj = clone $this; + $obj->result = $result; - return $this; + return $obj; } /** * @param Status::* $status */ - public function setStatus(string $status): self + public function withStatus(string $status): self { - $this->status = $status; + $obj = clone $this; + $obj->status = $status; - return $this; + return $obj; } - public function setUserPrompt(string $userPrompt): self + public function withUserPrompt(string $userPrompt): self { - $this->userPrompt = $userPrompt; + $obj = clone $this; + $obj->userPrompt = $userPrompt; - return $this; + return $obj; } } diff --git a/src/Searchscraper/CompletedSearchScraper/Status.php b/src/Searchscraper/CompletedSearchScraper/Status.php index cb362fa..68e49ff 100644 --- a/src/Searchscraper/CompletedSearchScraper/Status.php +++ b/src/Searchscraper/CompletedSearchScraper/Status.php @@ -4,15 +4,12 @@ namespace Scrapegraphai\Searchscraper\CompletedSearchScraper; -use Scrapegraphai\Core\Concerns\Enum; +use Scrapegraphai\Core\Concerns\SdkEnum; use Scrapegraphai\Core\Conversion\Contracts\ConverterSource; -/** - * @phpstan-type status_alias = Status::* - */ final class Status implements ConverterSource { - use Enum; + use SdkEnum; public const QUEUED = 'queued'; diff --git a/src/Searchscraper/SearchscraperCreateParams.php b/src/Searchscraper/SearchscraperCreateParams.php index 7901869..4dd94ee 100644 --- a/src/Searchscraper/SearchscraperCreateParams.php +++ b/src/Searchscraper/SearchscraperCreateParams.php @@ -5,26 +5,18 @@ namespace Scrapegraphai\Searchscraper; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; -use Scrapegraphai\Core\Concerns\Params; +use Scrapegraphai\Core\Concerns\SdkModel; +use Scrapegraphai\Core\Concerns\SdkParams; use Scrapegraphai\Core\Contracts\BaseModel; -use Scrapegraphai\Core\Conversion\MapOf; /** * Performs web search, selects relevant URLs, and extracts structured data from multiple websites. * Uses LLM to refine search queries and merge results from different sources. - * - * @phpstan-type create_params = array{ - * userPrompt: string, - * headers?: array, - * numResults?: int, - * outputSchema?: mixed, - * } */ final class SearchscraperCreateParams implements BaseModel { - use Model; - use Params; + use SdkModel; + use SdkParams; /** * Search query and extraction instruction. @@ -32,8 +24,8 @@ final class SearchscraperCreateParams implements BaseModel #[Api('user_prompt')] public string $userPrompt; - /** @var null|array $headers */ - #[Api(type: new MapOf('string'), optional: true)] + /** @var array|null $headers */ + #[Api(map: 'string', optional: true)] public ?array $headers; /** @@ -48,6 +40,20 @@ final class SearchscraperCreateParams implements BaseModel #[Api('output_schema', optional: true)] public mixed $outputSchema; + /** + * `new SearchscraperCreateParams()` is missing required properties by the API. + * + * To enforce required parameters use + * ``` + * SearchscraperCreateParams::with(userPrompt: ...) + * ``` + * + * Otherwise ensure the following setters are called + * + * ``` + * (new SearchscraperCreateParams)->withUserPrompt(...) + * ``` + */ public function __construct() { self::introspect(); @@ -59,9 +65,9 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. * - * @param null|array $headers + * @param array $headers */ - public static function from( + public static function with( string $userPrompt, ?array $headers = null, ?int $numResults = null, @@ -81,40 +87,44 @@ public static function from( /** * Search query and extraction instruction. */ - public function setUserPrompt(string $userPrompt): self + public function withUserPrompt(string $userPrompt): self { - $this->userPrompt = $userPrompt; + $obj = clone $this; + $obj->userPrompt = $userPrompt; - return $this; + return $obj; } /** * @param array $headers */ - public function setHeaders(array $headers): self + public function withHeaders(array $headers): self { - $this->headers = $headers; + $obj = clone $this; + $obj->headers = $headers; - return $this; + return $obj; } /** * Number of websites to scrape from search results. */ - public function setNumResults(int $numResults): self + public function withNumResults(int $numResults): self { - $this->numResults = $numResults; + $obj = clone $this; + $obj->numResults = $numResults; - return $this; + return $obj; } /** * JSON schema for structured output. */ - public function setOutputSchema(mixed $outputSchema): self + public function withOutputSchema(mixed $outputSchema): self { - $this->outputSchema = $outputSchema; + $obj = clone $this; + $obj->outputSchema = $outputSchema; - return $this; + return $obj; } } diff --git a/src/Services/CrawlService.php b/src/Services/CrawlService.php new file mode 100644 index 0000000..45e81d7 --- /dev/null +++ b/src/Services/CrawlService.php @@ -0,0 +1,103 @@ +client->request( + method: 'get', + path: ['crawl/%1$s', $taskID], + options: $requestOptions + ); + + // @phpstan-ignore-next-line; + return Conversion::coerce(CrawlGetResultsResponse::class, value: $resp); + } + + /** + * Initiate comprehensive website crawling with sitemap support. + * Supports both AI extraction mode and markdown conversion mode. + * Returns a task ID for async processing. + * + * @param string $url Starting URL for crawling + * @param int $depth Maximum crawl depth from starting URL + * @param bool $extractionMode Use AI extraction (true) or markdown conversion (false) + * @param int $maxPages Maximum number of pages to crawl + * @param string|null $prompt Extraction prompt (required if extraction_mode is true) + * @param bool $renderHeavyJs Enable heavy JavaScript rendering + * @param Rules $rules + * @param mixed $schema Output schema for extraction + * @param bool $sitemap Use sitemap for crawling + */ + public function start( + $url, + $depth = null, + $extractionMode = null, + $maxPages = null, + $prompt = null, + $renderHeavyJs = null, + $rules = null, + $schema = null, + $sitemap = null, + ?RequestOptions $requestOptions = null, + ): CrawlStartResponse { + $args = [ + 'url' => $url, + 'depth' => $depth, + 'extractionMode' => $extractionMode, + 'maxPages' => $maxPages, + 'prompt' => $prompt, + 'renderHeavyJs' => $renderHeavyJs, + 'rules' => $rules, + 'schema' => $schema, + 'sitemap' => $sitemap, + ]; + $args = Util::array_filter_null( + $args, + [ + 'depth', + 'extractionMode', + 'maxPages', + 'prompt', + 'renderHeavyJs', + 'rules', + 'schema', + 'sitemap', + ], + ); + [$parsed, $options] = CrawlStartParams::parseRequest( + $args, + $requestOptions + ); + $resp = $this->client->request( + method: 'post', + path: 'crawl', + body: (object) $parsed, + options: $options + ); + + // @phpstan-ignore-next-line; + return Conversion::coerce(CrawlStartResponse::class, value: $resp); + } +} diff --git a/src/Credits/CreditsService.php b/src/Services/CreditsService.php similarity index 95% rename from src/Credits/CreditsService.php rename to src/Services/CreditsService.php index 0384910..b52d91f 100644 --- a/src/Credits/CreditsService.php +++ b/src/Services/CreditsService.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Scrapegraphai\Credits; +namespace Scrapegraphai\Services; use Scrapegraphai\Client; use Scrapegraphai\Contracts\CreditsContract; diff --git a/src/Feedback/FeedbackService.php b/src/Services/FeedbackService.php similarity index 58% rename from src/Feedback/FeedbackService.php rename to src/Services/FeedbackService.php index 86ad79e..e40f052 100644 --- a/src/Feedback/FeedbackService.php +++ b/src/Services/FeedbackService.php @@ -2,11 +2,13 @@ declare(strict_types=1); -namespace Scrapegraphai\Feedback; +namespace Scrapegraphai\Services; use Scrapegraphai\Client; use Scrapegraphai\Contracts\FeedbackContract; use Scrapegraphai\Core\Conversion; +use Scrapegraphai\Core\Util; +use Scrapegraphai\Feedback\FeedbackSubmitParams; use Scrapegraphai\RequestOptions; use Scrapegraphai\Responses\Feedback\FeedbackSubmitResponse; @@ -17,16 +19,24 @@ public function __construct(private Client $client) {} /** * Submit feedback for a specific request. * - * @param array{ - * rating: int, requestID: string, feedbackText?: null|string - * }|FeedbackSubmitParams $params + * @param int $rating Rating score + * @param string $requestID Request to provide feedback for + * @param string|null $feedbackText Optional feedback comments */ public function submit( - array|FeedbackSubmitParams $params, - ?RequestOptions $requestOptions = null + $rating, + $requestID, + $feedbackText = null, + ?RequestOptions $requestOptions = null, ): FeedbackSubmitResponse { + $args = [ + 'rating' => $rating, + 'requestID' => $requestID, + 'feedbackText' => $feedbackText, + ]; + $args = Util::array_filter_null($args, ['feedbackText']); [$parsed, $options] = FeedbackSubmitParams::parseRequest( - $params, + $args, $requestOptions ); $resp = $this->client->request( diff --git a/src/GenerateSchema/GenerateSchemaService.php b/src/Services/GenerateSchemaService.php similarity index 77% rename from src/GenerateSchema/GenerateSchemaService.php rename to src/Services/GenerateSchemaService.php index 45bfe33..b0a8b44 100644 --- a/src/GenerateSchema/GenerateSchemaService.php +++ b/src/Services/GenerateSchemaService.php @@ -2,11 +2,13 @@ declare(strict_types=1); -namespace Scrapegraphai\GenerateSchema; +namespace Scrapegraphai\Services; use Scrapegraphai\Client; use Scrapegraphai\Contracts\GenerateSchemaContract; use Scrapegraphai\Core\Conversion; +use Scrapegraphai\Core\Util; +use Scrapegraphai\GenerateSchema\GenerateSchemaCreateParams; use Scrapegraphai\RequestOptions; use Scrapegraphai\Responses\GenerateSchema\GenerateSchemaGetResponse; use Scrapegraphai\Responses\GenerateSchema\GenerateSchemaGetResponse\CompletedSchemaGenerationResponse; @@ -21,16 +23,18 @@ public function __construct(private Client $client) {} * Generate or modify JSON schemas based on natural language descriptions. * Can create new schemas or extend existing ones. * - * @param array{ - * userPrompt: string, existingSchema?: mixed - * }|GenerateSchemaCreateParams $params + * @param string $userPrompt Natural language description of desired schema + * @param mixed $existingSchema Existing schema to modify or extend */ public function create( - array|GenerateSchemaCreateParams $params, - ?RequestOptions $requestOptions = null, + $userPrompt, + $existingSchema = null, + ?RequestOptions $requestOptions = null ): GenerateSchemaNewResponse { + $args = ['userPrompt' => $userPrompt, 'existingSchema' => $existingSchema]; + $args = Util::array_filter_null($args, ['existingSchema']); [$parsed, $options] = GenerateSchemaCreateParams::parseRequest( - $params, + $args, $requestOptions ); $resp = $this->client->request( diff --git a/src/Healthz/HealthzService.php b/src/Services/HealthzService.php similarity index 95% rename from src/Healthz/HealthzService.php rename to src/Services/HealthzService.php index 9b919de..4d7f3ab 100644 --- a/src/Healthz/HealthzService.php +++ b/src/Services/HealthzService.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Scrapegraphai\Healthz; +namespace Scrapegraphai\Services; use Scrapegraphai\Client; use Scrapegraphai\Contracts\HealthzContract; diff --git a/src/Markdownify/MarkdownifyService.php b/src/Services/MarkdownifyService.php similarity index 72% rename from src/Markdownify/MarkdownifyService.php rename to src/Services/MarkdownifyService.php index 4c88a29..70d9111 100644 --- a/src/Markdownify/MarkdownifyService.php +++ b/src/Services/MarkdownifyService.php @@ -2,11 +2,14 @@ declare(strict_types=1); -namespace Scrapegraphai\Markdownify; +namespace Scrapegraphai\Services; use Scrapegraphai\Client; use Scrapegraphai\Contracts\MarkdownifyContract; use Scrapegraphai\Core\Conversion; +use Scrapegraphai\Core\Util; +use Scrapegraphai\Markdownify\CompletedMarkdownify; +use Scrapegraphai\Markdownify\MarkdownifyConvertParams; use Scrapegraphai\RequestOptions; use Scrapegraphai\Responses\Markdownify\MarkdownifyGetStatusResponse; use Scrapegraphai\Responses\Markdownify\MarkdownifyGetStatusResponse\FailedMarkdownifyResponse; @@ -18,16 +21,22 @@ public function __construct(private Client $client) {} /** * Convert web page content to clean Markdown format. * - * @param array{ - * websiteURL: string, headers?: array, steps?: list - * }|MarkdownifyConvertParams $params + * @param string $websiteURL URL to convert to markdown + * @param array $headers + * @param list $steps Interaction steps before conversion */ public function convert( - array|MarkdownifyConvertParams $params, + $websiteURL, + $headers = null, + $steps = null, ?RequestOptions $requestOptions = null, ): CompletedMarkdownify { + $args = [ + 'websiteURL' => $websiteURL, 'headers' => $headers, 'steps' => $steps, + ]; + $args = Util::array_filter_null($args, ['headers', 'steps']); [$parsed, $options] = MarkdownifyConvertParams::parseRequest( - $params, + $args, $requestOptions ); $resp = $this->client->request( diff --git a/src/Searchscraper/SearchscraperService.php b/src/Services/SearchscraperService.php similarity index 67% rename from src/Searchscraper/SearchscraperService.php rename to src/Services/SearchscraperService.php index 45e5efe..e37ff3a 100644 --- a/src/Searchscraper/SearchscraperService.php +++ b/src/Services/SearchscraperService.php @@ -2,14 +2,17 @@ declare(strict_types=1); -namespace Scrapegraphai\Searchscraper; +namespace Scrapegraphai\Services; use Scrapegraphai\Client; use Scrapegraphai\Contracts\SearchscraperContract; use Scrapegraphai\Core\Conversion; +use Scrapegraphai\Core\Util; use Scrapegraphai\RequestOptions; use Scrapegraphai\Responses\Searchscraper\SearchscraperGetStatusResponse; use Scrapegraphai\Responses\Searchscraper\SearchscraperGetStatusResponse\FailedSearchScraperResponse; +use Scrapegraphai\Searchscraper\CompletedSearchScraper; +use Scrapegraphai\Searchscraper\SearchscraperCreateParams; final class SearchscraperService implements SearchscraperContract { @@ -19,19 +22,30 @@ public function __construct(private Client $client) {} * Performs web search, selects relevant URLs, and extracts structured data from multiple websites. * Uses LLM to refine search queries and merge results from different sources. * - * @param array{ - * userPrompt: string, - * headers?: array, - * numResults?: int, - * outputSchema?: mixed, - * }|SearchscraperCreateParams $params + * @param string $userPrompt Search query and extraction instruction + * @param array $headers + * @param int $numResults Number of websites to scrape from search results + * @param mixed $outputSchema JSON schema for structured output */ public function create( - array|SearchscraperCreateParams $params, + $userPrompt, + $headers = null, + $numResults = null, + $outputSchema = null, ?RequestOptions $requestOptions = null, ): CompletedSearchScraper { + $args = [ + 'userPrompt' => $userPrompt, + 'headers' => $headers, + 'numResults' => $numResults, + 'outputSchema' => $outputSchema, + ]; + $args = Util::array_filter_null( + $args, + ['headers', 'numResults', 'outputSchema'] + ); [$parsed, $options] = SearchscraperCreateParams::parseRequest( - $params, + $args, $requestOptions ); $resp = $this->client->request( diff --git a/src/Smartscraper/SmartscraperService.php b/src/Services/SmartscraperService.php similarity index 50% rename from src/Smartscraper/SmartscraperService.php rename to src/Services/SmartscraperService.php index 09f6806..846113a 100644 --- a/src/Smartscraper/SmartscraperService.php +++ b/src/Services/SmartscraperService.php @@ -2,14 +2,18 @@ declare(strict_types=1); -namespace Scrapegraphai\Smartscraper; +namespace Scrapegraphai\Services; use Scrapegraphai\Client; use Scrapegraphai\Contracts\SmartscraperContract; use Scrapegraphai\Core\Conversion; +use Scrapegraphai\Core\Util; use Scrapegraphai\RequestOptions; use Scrapegraphai\Responses\Smartscraper\SmartscraperGetResponse; use Scrapegraphai\Responses\Smartscraper\SmartscraperListResponse; +use Scrapegraphai\Smartscraper\CompletedSmartscraper; +use Scrapegraphai\Smartscraper\FailedSmartscraper; +use Scrapegraphai\Smartscraper\SmartscraperCreateParams; final class SmartscraperService implements SmartscraperContract { @@ -19,25 +23,58 @@ public function __construct(private Client $client) {} * Main scraping endpoint with LLM-powered content analysis. Supports various fetching providers, * infinite scrolling, pagination, and custom output schemas. * - * @param array{ - * userPrompt: string, - * cookies?: array, - * headers?: array, - * numberOfScrolls?: int, - * outputSchema?: mixed, - * renderHeavyJs?: bool, - * steps?: list, - * totalPages?: int, - * websiteHTML?: string, - * websiteURL?: string, - * }|SmartscraperCreateParams $params + * @param string $userPrompt Extraction instruction for the LLM + * @param array $cookies Cookies to include in the request + * @param array $headers HTTP headers to include in the request + * @param int $numberOfScrolls Number of infinite scroll operations to perform + * @param mixed $outputSchema JSON schema defining the expected output structure + * @param bool $renderHeavyJs Enable heavy JavaScript rendering + * @param list $steps Website interaction steps (e.g., clicking buttons) + * @param int $totalPages Number of pages to process for pagination + * @param string $websiteHTML HTML content to process (max 2MB, mutually exclusive with website_url) + * @param string $websiteURL URL to scrape (mutually exclusive with website_html) */ public function create( - array|SmartscraperCreateParams $params, + $userPrompt, + $cookies = null, + $headers = null, + $numberOfScrolls = null, + $outputSchema = null, + $renderHeavyJs = null, + $steps = null, + $totalPages = null, + $websiteHTML = null, + $websiteURL = null, ?RequestOptions $requestOptions = null, ): CompletedSmartscraper { + $args = [ + 'userPrompt' => $userPrompt, + 'cookies' => $cookies, + 'headers' => $headers, + 'numberOfScrolls' => $numberOfScrolls, + 'outputSchema' => $outputSchema, + 'renderHeavyJs' => $renderHeavyJs, + 'steps' => $steps, + 'totalPages' => $totalPages, + 'websiteHTML' => $websiteHTML, + 'websiteURL' => $websiteURL, + ]; + $args = Util::array_filter_null( + $args, + [ + 'cookies', + 'headers', + 'numberOfScrolls', + 'outputSchema', + 'renderHeavyJs', + 'steps', + 'totalPages', + 'websiteHTML', + 'websiteURL', + ], + ); [$parsed, $options] = SmartscraperCreateParams::parseRequest( - $params, + $args, $requestOptions ); $resp = $this->client->request( diff --git a/src/Validate/ValidateService.php b/src/Services/ValidateService.php similarity index 95% rename from src/Validate/ValidateService.php rename to src/Services/ValidateService.php index e40031a..31ec544 100644 --- a/src/Validate/ValidateService.php +++ b/src/Services/ValidateService.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Scrapegraphai\Validate; +namespace Scrapegraphai\Services; use Scrapegraphai\Client; use Scrapegraphai\Contracts\ValidateContract; diff --git a/src/Smartscraper/CompletedSmartscraper.php b/src/Smartscraper/CompletedSmartscraper.php index 288bc66..684284b 100644 --- a/src/Smartscraper/CompletedSmartscraper.php +++ b/src/Smartscraper/CompletedSmartscraper.php @@ -5,23 +5,13 @@ namespace Scrapegraphai\Smartscraper; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; +use Scrapegraphai\Core\Concerns\SdkModel; use Scrapegraphai\Core\Contracts\BaseModel; use Scrapegraphai\Smartscraper\CompletedSmartscraper\Status; -/** - * @phpstan-type completed_smartscraper_alias = array{ - * error?: string, - * requestID?: string, - * result?: mixed, - * status?: Status::*, - * userPrompt?: string, - * websiteURL?: string|null, - * } - */ final class CompletedSmartscraper implements BaseModel { - use Model; + use SdkModel; /** * Error message (empty on success). @@ -38,13 +28,13 @@ final class CompletedSmartscraper implements BaseModel /** * Extracted data based on prompt/schema. */ - #[Api(optional: true)] + #[Api(nullable: true, optional: true)] public mixed $result; /** * Processing status. * - * @var null|Status::* $status + * @var Status::*|null $status */ #[Api(enum: Status::class, optional: true)] public ?string $status; @@ -52,7 +42,7 @@ final class CompletedSmartscraper implements BaseModel #[Api('user_prompt', optional: true)] public ?string $userPrompt; - #[Api('website_url', optional: true)] + #[Api('website_url', nullable: true, optional: true)] public ?string $websiteURL; public function __construct() @@ -66,9 +56,9 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. * - * @param null|Status::* $status + * @param Status::* $status */ - public static function from( + public static function with( ?string $error = null, ?string $requestID = null, mixed $result = null, @@ -91,31 +81,34 @@ public static function from( /** * Error message (empty on success). */ - public function setError(string $error): self + public function withError(string $error): self { - $this->error = $error; + $obj = clone $this; + $obj->error = $error; - return $this; + return $obj; } /** * Unique request identifier. */ - public function setRequestID(string $requestID): self + public function withRequestID(string $requestID): self { - $this->requestID = $requestID; + $obj = clone $this; + $obj->requestID = $requestID; - return $this; + return $obj; } /** * Extracted data based on prompt/schema. */ - public function setResult(mixed $result): self + public function withResult(mixed $result): self { - $this->result = $result; + $obj = clone $this; + $obj->result = $result; - return $this; + return $obj; } /** @@ -123,24 +116,27 @@ public function setResult(mixed $result): self * * @param Status::* $status */ - public function setStatus(string $status): self + public function withStatus(string $status): self { - $this->status = $status; + $obj = clone $this; + $obj->status = $status; - return $this; + return $obj; } - public function setUserPrompt(string $userPrompt): self + public function withUserPrompt(string $userPrompt): self { - $this->userPrompt = $userPrompt; + $obj = clone $this; + $obj->userPrompt = $userPrompt; - return $this; + return $obj; } - public function setWebsiteURL(?string $websiteURL): self + public function withWebsiteURL(?string $websiteURL): self { - $this->websiteURL = $websiteURL; + $obj = clone $this; + $obj->websiteURL = $websiteURL; - return $this; + return $obj; } } diff --git a/src/Smartscraper/CompletedSmartscraper/Status.php b/src/Smartscraper/CompletedSmartscraper/Status.php index e2569bf..1b66e4b 100644 --- a/src/Smartscraper/CompletedSmartscraper/Status.php +++ b/src/Smartscraper/CompletedSmartscraper/Status.php @@ -4,17 +4,15 @@ namespace Scrapegraphai\Smartscraper\CompletedSmartscraper; -use Scrapegraphai\Core\Concerns\Enum; +use Scrapegraphai\Core\Concerns\SdkEnum; use Scrapegraphai\Core\Conversion\Contracts\ConverterSource; /** * Processing status. - * - * @phpstan-type status_alias = Status::* */ final class Status implements ConverterSource { - use Enum; + use SdkEnum; public const QUEUED = 'queued'; diff --git a/src/Smartscraper/FailedSmartscraper.php b/src/Smartscraper/FailedSmartscraper.php index 7bd42e0..5d2411d 100644 --- a/src/Smartscraper/FailedSmartscraper.php +++ b/src/Smartscraper/FailedSmartscraper.php @@ -5,23 +5,13 @@ namespace Scrapegraphai\Smartscraper; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; +use Scrapegraphai\Core\Concerns\SdkModel; use Scrapegraphai\Core\Contracts\BaseModel; use Scrapegraphai\Smartscraper\FailedSmartscraper\Status; -/** - * @phpstan-type failed_smartscraper_alias = array{ - * error?: string, - * requestID?: string, - * result?: mixed, - * status?: Status::*, - * userPrompt?: string, - * websiteURL?: string|null, - * } - */ final class FailedSmartscraper implements BaseModel { - use Model; + use SdkModel; /** * Error description. @@ -32,17 +22,17 @@ final class FailedSmartscraper implements BaseModel #[Api('request_id', optional: true)] public ?string $requestID; - #[Api(optional: true)] + #[Api(nullable: true, optional: true)] public mixed $result; - /** @var null|Status::* $status */ + /** @var Status::*|null $status */ #[Api(enum: Status::class, optional: true)] public ?string $status; #[Api('user_prompt', optional: true)] public ?string $userPrompt; - #[Api('website_url', optional: true)] + #[Api('website_url', nullable: true, optional: true)] public ?string $websiteURL; public function __construct() @@ -56,9 +46,9 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. * - * @param null|Status::* $status + * @param Status::* $status */ - public static function from( + public static function with( ?string $error = null, ?string $requestID = null, mixed $result = null, @@ -81,48 +71,54 @@ public static function from( /** * Error description. */ - public function setError(string $error): self + public function withError(string $error): self { - $this->error = $error; + $obj = clone $this; + $obj->error = $error; - return $this; + return $obj; } - public function setRequestID(string $requestID): self + public function withRequestID(string $requestID): self { - $this->requestID = $requestID; + $obj = clone $this; + $obj->requestID = $requestID; - return $this; + return $obj; } - public function setResult(mixed $result): self + public function withResult(mixed $result): self { - $this->result = $result; + $obj = clone $this; + $obj->result = $result; - return $this; + return $obj; } /** * @param Status::* $status */ - public function setStatus(string $status): self + public function withStatus(string $status): self { - $this->status = $status; + $obj = clone $this; + $obj->status = $status; - return $this; + return $obj; } - public function setUserPrompt(string $userPrompt): self + public function withUserPrompt(string $userPrompt): self { - $this->userPrompt = $userPrompt; + $obj = clone $this; + $obj->userPrompt = $userPrompt; - return $this; + return $obj; } - public function setWebsiteURL(?string $websiteURL): self + public function withWebsiteURL(?string $websiteURL): self { - $this->websiteURL = $websiteURL; + $obj = clone $this; + $obj->websiteURL = $websiteURL; - return $this; + return $obj; } } diff --git a/src/Smartscraper/FailedSmartscraper/Status.php b/src/Smartscraper/FailedSmartscraper/Status.php index b5b7bd8..ef18e98 100644 --- a/src/Smartscraper/FailedSmartscraper/Status.php +++ b/src/Smartscraper/FailedSmartscraper/Status.php @@ -4,15 +4,12 @@ namespace Scrapegraphai\Smartscraper\FailedSmartscraper; -use Scrapegraphai\Core\Concerns\Enum; +use Scrapegraphai\Core\Concerns\SdkEnum; use Scrapegraphai\Core\Conversion\Contracts\ConverterSource; -/** - * @phpstan-type status_alias = Status::* - */ final class Status implements ConverterSource { - use Enum; + use SdkEnum; public const FAILED = 'failed'; } diff --git a/src/Smartscraper/SmartscraperCreateParams.php b/src/Smartscraper/SmartscraperCreateParams.php index 77f2885..44867ef 100644 --- a/src/Smartscraper/SmartscraperCreateParams.php +++ b/src/Smartscraper/SmartscraperCreateParams.php @@ -5,33 +5,18 @@ namespace Scrapegraphai\Smartscraper; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; -use Scrapegraphai\Core\Concerns\Params; +use Scrapegraphai\Core\Concerns\SdkModel; +use Scrapegraphai\Core\Concerns\SdkParams; use Scrapegraphai\Core\Contracts\BaseModel; -use Scrapegraphai\Core\Conversion\ListOf; -use Scrapegraphai\Core\Conversion\MapOf; /** * Main scraping endpoint with LLM-powered content analysis. Supports various fetching providers, * infinite scrolling, pagination, and custom output schemas. - * - * @phpstan-type create_params = array{ - * userPrompt: string, - * cookies?: array, - * headers?: array, - * numberOfScrolls?: int, - * outputSchema?: mixed, - * renderHeavyJs?: bool, - * steps?: list, - * totalPages?: int, - * websiteHTML?: string, - * websiteURL?: string, - * } */ final class SmartscraperCreateParams implements BaseModel { - use Model; - use Params; + use SdkModel; + use SdkParams; /** * Extraction instruction for the LLM. @@ -42,17 +27,17 @@ final class SmartscraperCreateParams implements BaseModel /** * Cookies to include in the request. * - * @var null|array $cookies + * @var array|null $cookies */ - #[Api(type: new MapOf('string'), optional: true)] + #[Api(map: 'string', optional: true)] public ?array $cookies; /** * HTTP headers to include in the request. * - * @var null|array $headers + * @var array|null $headers */ - #[Api(type: new MapOf('string'), optional: true)] + #[Api(map: 'string', optional: true)] public ?array $headers; /** @@ -76,9 +61,9 @@ final class SmartscraperCreateParams implements BaseModel /** * Website interaction steps (e.g., clicking buttons). * - * @var null|list $steps + * @var list|null $steps */ - #[Api(type: new ListOf('string'), optional: true)] + #[Api(list: 'string', optional: true)] public ?array $steps; /** @@ -99,6 +84,20 @@ final class SmartscraperCreateParams implements BaseModel #[Api('website_url', optional: true)] public ?string $websiteURL; + /** + * `new SmartscraperCreateParams()` is missing required properties by the API. + * + * To enforce required parameters use + * ``` + * SmartscraperCreateParams::with(userPrompt: ...) + * ``` + * + * Otherwise ensure the following setters are called + * + * ``` + * (new SmartscraperCreateParams)->withUserPrompt(...) + * ``` + */ public function __construct() { self::introspect(); @@ -110,11 +109,11 @@ public function __construct() * * You must use named parameters to construct any parameters with a default value. * - * @param null|array $cookies - * @param null|array $headers - * @param null|list $steps + * @param array $cookies + * @param array $headers + * @param list $steps */ - public static function from( + public static function with( string $userPrompt, ?array $cookies = null, ?array $headers = null, @@ -146,11 +145,12 @@ public static function from( /** * Extraction instruction for the LLM. */ - public function setUserPrompt(string $userPrompt): self + public function withUserPrompt(string $userPrompt): self { - $this->userPrompt = $userPrompt; + $obj = clone $this; + $obj->userPrompt = $userPrompt; - return $this; + return $obj; } /** @@ -158,11 +158,12 @@ public function setUserPrompt(string $userPrompt): self * * @param array $cookies */ - public function setCookies(array $cookies): self + public function withCookies(array $cookies): self { - $this->cookies = $cookies; + $obj = clone $this; + $obj->cookies = $cookies; - return $this; + return $obj; } /** @@ -170,41 +171,45 @@ public function setCookies(array $cookies): self * * @param array $headers */ - public function setHeaders(array $headers): self + public function withHeaders(array $headers): self { - $this->headers = $headers; + $obj = clone $this; + $obj->headers = $headers; - return $this; + return $obj; } /** * Number of infinite scroll operations to perform. */ - public function setNumberOfScrolls(int $numberOfScrolls): self + public function withNumberOfScrolls(int $numberOfScrolls): self { - $this->numberOfScrolls = $numberOfScrolls; + $obj = clone $this; + $obj->numberOfScrolls = $numberOfScrolls; - return $this; + return $obj; } /** * JSON schema defining the expected output structure. */ - public function setOutputSchema(mixed $outputSchema): self + public function withOutputSchema(mixed $outputSchema): self { - $this->outputSchema = $outputSchema; + $obj = clone $this; + $obj->outputSchema = $outputSchema; - return $this; + return $obj; } /** * Enable heavy JavaScript rendering. */ - public function setRenderHeavyJs(bool $renderHeavyJs): self + public function withRenderHeavyJs(bool $renderHeavyJs): self { - $this->renderHeavyJs = $renderHeavyJs; + $obj = clone $this; + $obj->renderHeavyJs = $renderHeavyJs; - return $this; + return $obj; } /** @@ -212,40 +217,44 @@ public function setRenderHeavyJs(bool $renderHeavyJs): self * * @param list $steps */ - public function setSteps(array $steps): self + public function withSteps(array $steps): self { - $this->steps = $steps; + $obj = clone $this; + $obj->steps = $steps; - return $this; + return $obj; } /** * Number of pages to process for pagination. */ - public function setTotalPages(int $totalPages): self + public function withTotalPages(int $totalPages): self { - $this->totalPages = $totalPages; + $obj = clone $this; + $obj->totalPages = $totalPages; - return $this; + return $obj; } /** * HTML content to process (max 2MB, mutually exclusive with website_url). */ - public function setWebsiteHTML(string $websiteHTML): self + public function withWebsiteHTML(string $websiteHTML): self { - $this->websiteHTML = $websiteHTML; + $obj = clone $this; + $obj->websiteHTML = $websiteHTML; - return $this; + return $obj; } /** * URL to scrape (mutually exclusive with website_html). */ - public function setWebsiteURL(string $websiteURL): self + public function withWebsiteURL(string $websiteURL): self { - $this->websiteURL = $websiteURL; + $obj = clone $this; + $obj->websiteURL = $websiteURL; - return $this; + return $obj; } } diff --git a/tests/Core/TestModel.php b/tests/Core/TestModel.php index 1b2e6c9..6e07607 100644 --- a/tests/Core/TestModel.php +++ b/tests/Core/TestModel.php @@ -6,12 +6,12 @@ use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Scrapegraphai\Core\Attributes\Api; -use Scrapegraphai\Core\Concerns\Model; +use Scrapegraphai\Core\Concerns\SdkModel; use Scrapegraphai\Core\Contracts\BaseModel; class TestModel implements BaseModel { - use Model; + use SdkModel; #[Api] public string $name; @@ -19,7 +19,7 @@ class TestModel implements BaseModel #[Api('age_years')] public int $ageYears; - /** @var null|list */ + /** @var list|null */ #[Api(optional: true)] public ?array $friends; @@ -27,7 +27,7 @@ class TestModel implements BaseModel public ?string $owner; /** - * @param null|list $friends + * @param list|null $friends */ public function __construct( string $name, diff --git a/tests/Resources/CrawlTest.php b/tests/Resources/CrawlTest.php index 97139dd..c46a37f 100644 --- a/tests/Resources/CrawlTest.php +++ b/tests/Resources/CrawlTest.php @@ -6,8 +6,6 @@ use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Scrapegraphai\Client; -use Scrapegraphai\Crawl\CrawlStartParams; -use Scrapegraphai\Crawl\CrawlStartParams\Rules; use Tests\UnsupportedMockTests; /** @@ -47,8 +45,7 @@ public function testStart(): void $this->markTestSkipped('Prism tests are disabled'); } - $params = CrawlStartParams::from(url: 'https://example.com'); - $result = $this->client->crawl->start($params); + $result = $this->client->crawl->start(url: 'https://example.com'); $this->assertTrue(true); // @phpstan-ignore-line } @@ -60,18 +57,7 @@ public function testStartWithOptionalParams(): void $this->markTestSkipped('Prism tests are disabled'); } - $params = CrawlStartParams::from( - url: 'https://example.com', - depth: 0, - extractionMode: true, - maxPages: 1, - prompt: 'prompt', - renderHeavyJs: true, - rules: (new Rules)->setExclude(['string'])->setSameDomain(true), - schema: (object) [], - sitemap: true, - ); - $result = $this->client->crawl->start($params); + $result = $this->client->crawl->start(url: 'https://example.com'); $this->assertTrue(true); // @phpstan-ignore-line } diff --git a/tests/Resources/FeedbackTest.php b/tests/Resources/FeedbackTest.php index 2da6474..1659f58 100644 --- a/tests/Resources/FeedbackTest.php +++ b/tests/Resources/FeedbackTest.php @@ -6,7 +6,6 @@ use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Scrapegraphai\Client; -use Scrapegraphai\Feedback\FeedbackSubmitParams; use Tests\UnsupportedMockTests; /** @@ -34,11 +33,10 @@ public function testSubmit(): void $this->markTestSkipped('Prism tests are disabled'); } - $params = FeedbackSubmitParams::from( + $result = $this->client->feedback->submit( rating: 0, requestID: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e' ); - $result = $this->client->feedback->submit($params); $this->assertTrue(true); // @phpstan-ignore-line } @@ -50,12 +48,10 @@ public function testSubmitWithOptionalParams(): void $this->markTestSkipped('Prism tests are disabled'); } - $params = FeedbackSubmitParams::from( + $result = $this->client->feedback->submit( rating: 0, - requestID: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', - feedbackText: 'feedback_text', + requestID: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e' ); - $result = $this->client->feedback->submit($params); $this->assertTrue(true); // @phpstan-ignore-line } diff --git a/tests/Resources/GenerateSchemaTest.php b/tests/Resources/GenerateSchemaTest.php index a148898..69cd3ba 100644 --- a/tests/Resources/GenerateSchemaTest.php +++ b/tests/Resources/GenerateSchemaTest.php @@ -6,7 +6,6 @@ use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Scrapegraphai\Client; -use Scrapegraphai\GenerateSchema\GenerateSchemaCreateParams; use Tests\UnsupportedMockTests; /** @@ -34,10 +33,9 @@ public function testCreate(): void $this->markTestSkipped('Prism tests are disabled'); } - $params = GenerateSchemaCreateParams::from( + $result = $this->client->generateSchema->create( userPrompt: 'Create a schema for product information including name, price, and reviews', ); - $result = $this->client->generateSchema->create($params); $this->assertTrue(true); // @phpstan-ignore-line } @@ -49,11 +47,9 @@ public function testCreateWithOptionalParams(): void $this->markTestSkipped('Prism tests are disabled'); } - $params = GenerateSchemaCreateParams::from( + $result = $this->client->generateSchema->create( userPrompt: 'Create a schema for product information including name, price, and reviews', - existingSchema: (object) [], ); - $result = $this->client->generateSchema->create($params); $this->assertTrue(true); // @phpstan-ignore-line } @@ -65,11 +61,9 @@ public function testRetrieve(): void $this->markTestSkipped('Prism tests are disabled'); } - $result = $this - ->client - ->generateSchema - ->retrieve('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e') - ; + $result = $this->client->generateSchema->retrieve( + '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e' + ); $this->assertTrue(true); // @phpstan-ignore-line } diff --git a/tests/Resources/MarkdownifyTest.php b/tests/Resources/MarkdownifyTest.php index 0b7866d..d60d5fd 100644 --- a/tests/Resources/MarkdownifyTest.php +++ b/tests/Resources/MarkdownifyTest.php @@ -6,7 +6,6 @@ use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Scrapegraphai\Client; -use Scrapegraphai\Markdownify\MarkdownifyConvertParams; use Tests\UnsupportedMockTests; /** @@ -34,8 +33,9 @@ public function testConvert(): void $this->markTestSkipped('Prism tests are disabled'); } - $params = MarkdownifyConvertParams::from(websiteURL: 'https://example.com'); - $result = $this->client->markdownify->convert($params); + $result = $this->client->markdownify->convert( + websiteURL: 'https://example.com' + ); $this->assertTrue(true); // @phpstan-ignore-line } @@ -47,12 +47,9 @@ public function testConvertWithOptionalParams(): void $this->markTestSkipped('Prism tests are disabled'); } - $params = MarkdownifyConvertParams::from( - websiteURL: 'https://example.com', - headers: ['foo' => 'string'], - steps: ['string'], + $result = $this->client->markdownify->convert( + websiteURL: 'https://example.com' ); - $result = $this->client->markdownify->convert($params); $this->assertTrue(true); // @phpstan-ignore-line } @@ -64,11 +61,9 @@ public function testRetrieveStatus(): void $this->markTestSkipped('Prism tests are disabled'); } - $result = $this - ->client - ->markdownify - ->retrieveStatus('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e') - ; + $result = $this->client->markdownify->retrieveStatus( + '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e' + ); $this->assertTrue(true); // @phpstan-ignore-line } diff --git a/tests/Resources/SearchscraperTest.php b/tests/Resources/SearchscraperTest.php index d355d3c..70491fc 100644 --- a/tests/Resources/SearchscraperTest.php +++ b/tests/Resources/SearchscraperTest.php @@ -6,7 +6,6 @@ use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Scrapegraphai\Client; -use Scrapegraphai\Searchscraper\SearchscraperCreateParams; use Tests\UnsupportedMockTests; /** @@ -34,10 +33,9 @@ public function testCreate(): void $this->markTestSkipped('Prism tests are disabled'); } - $params = SearchscraperCreateParams::from( + $result = $this->client->searchscraper->create( userPrompt: 'Find the latest AI news and extract headlines and summaries' ); - $result = $this->client->searchscraper->create($params); $this->assertTrue(true); // @phpstan-ignore-line } @@ -49,13 +47,9 @@ public function testCreateWithOptionalParams(): void $this->markTestSkipped('Prism tests are disabled'); } - $params = SearchscraperCreateParams::from( - userPrompt: 'Find the latest AI news and extract headlines and summaries', - headers: ['foo' => 'string'], - numResults: 3, - outputSchema: (object) [], + $result = $this->client->searchscraper->create( + userPrompt: 'Find the latest AI news and extract headlines and summaries' ); - $result = $this->client->searchscraper->create($params); $this->assertTrue(true); // @phpstan-ignore-line } @@ -67,11 +61,9 @@ public function testRetrieveStatus(): void $this->markTestSkipped('Prism tests are disabled'); } - $result = $this - ->client - ->searchscraper - ->retrieveStatus('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e') - ; + $result = $this->client->searchscraper->retrieveStatus( + '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e' + ); $this->assertTrue(true); // @phpstan-ignore-line } diff --git a/tests/Resources/SmartscraperTest.php b/tests/Resources/SmartscraperTest.php index 2ae80d5..803a2f3 100644 --- a/tests/Resources/SmartscraperTest.php +++ b/tests/Resources/SmartscraperTest.php @@ -6,7 +6,6 @@ use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Scrapegraphai\Client; -use Scrapegraphai\Smartscraper\SmartscraperCreateParams; use Tests\UnsupportedMockTests; /** @@ -34,10 +33,9 @@ public function testCreate(): void $this->markTestSkipped('Prism tests are disabled'); } - $params = SmartscraperCreateParams::from( + $result = $this->client->smartscraper->create( userPrompt: 'Extract the product name, price, and description' ); - $result = $this->client->smartscraper->create($params); $this->assertTrue(true); // @phpstan-ignore-line } @@ -49,19 +47,9 @@ public function testCreateWithOptionalParams(): void $this->markTestSkipped('Prism tests are disabled'); } - $params = SmartscraperCreateParams::from( - userPrompt: 'Extract the product name, price, and description', - cookies: ['foo' => 'string'], - headers: ['foo' => 'string'], - numberOfScrolls: 0, - outputSchema: (object) [], - renderHeavyJs: true, - steps: ['string'], - totalPages: 1, - websiteHTML: 'website_html', - websiteURL: 'https://example.com/product', + $result = $this->client->smartscraper->create( + userPrompt: 'Extract the product name, price, and description' ); - $result = $this->client->smartscraper->create($params); $this->assertTrue(true); // @phpstan-ignore-line } @@ -73,11 +61,9 @@ public function testRetrieve(): void $this->markTestSkipped('Prism tests are disabled'); } - $result = $this - ->client - ->smartscraper - ->retrieve('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e') - ; + $result = $this->client->smartscraper->retrieve( + '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e' + ); $this->assertTrue(true); // @phpstan-ignore-line }