diff --git a/composer.json b/composer.json index ff8b1fb..0a03b39 100644 --- a/composer.json +++ b/composer.json @@ -20,6 +20,7 @@ ], "require": { "php": ">=7.3", + "ext-json": "*", "nesk/rialto": "^1.2.0", "psr/log": "^1.0", "vierbergenlars/php-semver": "^3.0.2" @@ -42,7 +43,8 @@ }, "scripts": { "post-install-cmd": "npm install", - "test": "./vendor/bin/phpunit" + "test": "./vendor/bin/phpunit", + "update-docs": "php bin/console doc:generate" }, "config": { "sort-packages": true diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..1c79bb0 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,9 @@ +parameters: + level: max + paths: + - src + fileExtensions: + - php + parallel: + maximumNumberOfProcesses: 4 + tipsOfTheDay: false \ No newline at end of file diff --git a/src/Command/GenerateDocumentationCommand.php b/src/Command/GenerateDocumentationCommand.php index 9d46d3b..e32746d 100644 --- a/src/Command/GenerateDocumentationCommand.php +++ b/src/Command/GenerateDocumentationCommand.php @@ -17,6 +17,9 @@ final class GenerateDocumentationCommand extends Command private const NODE_MODULES_DIR = __DIR__.'/../../node_modules'; private const RESOURCES_DIR = __DIR__.'/../Resources'; private const RESOURCES_NAMESPACE = 'Nesk\\Puphpeteer\\Resources'; + private const DOC_FORMAT_PHP = 'php'; + private const DOC_FORMAT_PHPSTAN = 'phpstan'; + private const DOC_FORMATS = [self::DOC_FORMAT_PHP, self::DOC_FORMAT_PHPSTAN]; protected static $defaultName = 'doc:generate'; @@ -36,6 +39,7 @@ protected function configure(): void */ private static function buildDocumentationGenerator(): void { + self::rmdirRecursive(self::BUILD_DIR); $process = new Process([ self::NODE_MODULES_DIR.'/.bin/tsc', '--outDir', @@ -55,23 +59,35 @@ private static function getDocumentation(string $puppeteerPath, array $resourceN $commonFiles = \glob("$puppeteerPath/lib/esm/puppeteer/common/*.d.ts"); $nodeFiles = \glob("$puppeteerPath/lib/esm/puppeteer/node/*.d.ts"); - $process = new Process( - \array_merge( - ['node', self::BUILD_DIR.'/'.self::DOC_FILE_NAME.'.js', 'php'], - $commonFiles, - $nodeFiles, - ['--resources-namespace', self::RESOURCES_NAMESPACE, '--resources'], - $resourceNames - ) - ); - $process->mustRun(); + $result = []; + foreach(self::DOC_FORMATS as $format) { + $process = new Process( + \array_merge( + ['node', self::BUILD_DIR.'/'.self::DOC_FILE_NAME.'.js', $format], + $commonFiles, + $nodeFiles, + ['--resources-namespace', self::RESOURCES_NAMESPACE, '--resources'], + $resourceNames + ) + ); + $process->mustRun(); + + foreach (\json_decode($process->getOutput(), true) as &$class) { + $result[$class['name']]['name'] = $class['name']; + $result[$class['name']][$format] = [ + 'properties' => $class['properties'], + 'getters' => $class['getters'], + 'methods' => $class['methods'], + ]; + } + } - return \json_decode($process->getOutput(), true); + return $result; } private static function getResourceNames(): array { - return array_map(function (string $filePath): string { + return array_map(static function (string $filePath): string { return explode('.', \basename($filePath))[0]; }, \glob(self::RESOURCES_DIR.'/*')); } @@ -80,18 +96,23 @@ private static function generatePhpDocWithDocumentation(array $classDocumentatio { $properties = array_map(function (string $property): string { return "\n * @property $property"; - }, $classDocumentation['properties']); + }, $classDocumentation[self::DOC_FORMAT_PHP]['properties']); $properties = \implode('', $properties); $getters = array_map(function (string $getter): string { return "\n * @property-read $getter"; - }, $classDocumentation['getters']); + }, $classDocumentation[self::DOC_FORMAT_PHP]['getters']); $getters = \implode('', $getters); - $methods = array_map(function (string $method): string { - return "\n * @method $method"; - }, $classDocumentation['methods']); - $methods = \implode('', $methods); + $methods = ''; + foreach ($classDocumentation[self::DOC_FORMAT_PHP]['methods'] as $pos => $method) { + $methods .= "\n * @method $method"; + + $phpStanMethod = $classDocumentation[self::DOC_FORMAT_PHPSTAN]['methods'][$pos]; + //phpStorm works incorrectly if @phpstan-method is used. + //Using non-standard method-extended phpDoc: + $methods .= "\n * @method-extended $phpStanMethod"; + } if (\strlen($properties) > 0 || \strlen($getters) > 0 || \strlen($methods) > 0) { return "/**$properties$getters$methods\n */"; @@ -155,7 +176,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int } // Handle the specific Puppeteer class - $classDocumentation = $documentation['Puppeteer'] ?? null; + $classDocumentation = array_replace_recursive($documentation['Puppeteer'], $documentation['PuppeteerNode']); + unset($documentation['Puppeteer'], $documentation['PuppeteerNode']); if ($classDocumentation !== null) { $phpDoc = self::generatePhpDocWithDocumentation($classDocumentation); if ($phpDoc !== null) { @@ -175,4 +197,16 @@ protected function execute(InputInterface $input, OutputInterface $output): int return 0; } + + private static function rmdirRecursive(string $dir): bool { + $files = scandir($dir); + if (!is_array($files)) { + return false; + } + $files = array_diff($files, array('.','..')); + foreach ($files as $file) { + (is_dir("$dir/$file")) ? self::rmdirRecursive("$dir/$file") : unlink("$dir/$file"); + } + return rmdir($dir); + } } diff --git a/src/Puppeteer.php b/src/Puppeteer.php index ed8bac3..bd8b4b7 100644 --- a/src/Puppeteer.php +++ b/src/Puppeteer.php @@ -2,6 +2,8 @@ namespace Nesk\Puphpeteer; +use Nesk\Puphpeteer\Resources\Browser; +use Nesk\Puphpeteer\Resources\BrowserFetcher; use Psr\Log\LoggerInterface; use Symfony\Component\Process\Process; use Nesk\Rialto\AbstractEntryPoint; @@ -10,11 +12,25 @@ /** * @property-read mixed devices * @property-read mixed errors - * @method \Nesk\Puphpeteer\Resources\Browser connect(array $options) + * @property-read string product + * @method \Nesk\Puphpeteer\Resources\Browser connect(array $options) + * @method-extended \Nesk\Puphpeteer\Resources\Browser connect(array $options) * @method void registerCustomQueryHandler(string $name, mixed $queryHandler) + * @method-extended void registerCustomQueryHandler(string $name, mixed $queryHandler) * @method void unregisterCustomQueryHandler(string $name) + * @method-extended void unregisterCustomQueryHandler(string $name) * @method string[] customQueryHandlerNames() + * @method-extended string[] customQueryHandlerNames() * @method void clearCustomQueryHandlers() + * @method-extended void clearCustomQueryHandlers() + * @method \Nesk\Puphpeteer\Resources\Browser launch(array $options = []) + * @method-extended \Nesk\Puphpeteer\Resources\Browser launch(array&array{ product: mixed, extraPrefsFirefox: array|string[]|mixed[] } $options = null) + * @method string executablePath() + * @method-extended string executablePath() + * @method string[] defaultArgs(array $options = []) + * @method-extended string[] defaultArgs(array $options = null) + * @method \Nesk\Puphpeteer\Resources\BrowserFetcher createBrowserFetcher(array $options) + * @method-extended \Nesk\Puphpeteer\Resources\BrowserFetcher createBrowserFetcher(array $options) */ class Puppeteer extends AbstractEntryPoint { diff --git a/src/Resources/Accessibility.php b/src/Resources/Accessibility.php index 34526d9..2652cf2 100644 --- a/src/Resources/Accessibility.php +++ b/src/Resources/Accessibility.php @@ -5,7 +5,8 @@ use Nesk\Rialto\Data\BasicResource; /** - * @method mixed snapshot(array $options = null) + * @method mixed snapshot(array $options = []) + * @method-extended mixed snapshot(array $options = null) */ class Accessibility extends BasicResource { diff --git a/src/Resources/Browser.php b/src/Resources/Browser.php index a01b14a..bf69864 100644 --- a/src/Resources/Browser.php +++ b/src/Resources/Browser.php @@ -4,20 +4,35 @@ /** * @method mixed|null process() + * @method-extended mixed|null process() * @method \Nesk\Puphpeteer\Resources\BrowserContext createIncognitoBrowserContext() + * @method-extended \Nesk\Puphpeteer\Resources\BrowserContext createIncognitoBrowserContext() * @method \Nesk\Puphpeteer\Resources\BrowserContext[] browserContexts() + * @method-extended \Nesk\Puphpeteer\Resources\BrowserContext[] browserContexts() * @method \Nesk\Puphpeteer\Resources\BrowserContext defaultBrowserContext() + * @method-extended \Nesk\Puphpeteer\Resources\BrowserContext defaultBrowserContext() * @method string wsEndpoint() + * @method-extended string wsEndpoint() * @method \Nesk\Puphpeteer\Resources\Page newPage() + * @method-extended \Nesk\Puphpeteer\Resources\Page newPage() * @method \Nesk\Puphpeteer\Resources\Target[] targets() + * @method-extended \Nesk\Puphpeteer\Resources\Target[] targets() * @method \Nesk\Puphpeteer\Resources\Target target() - * @method \Nesk\Puphpeteer\Resources\Target waitForTarget(callable(\Nesk\Puphpeteer\Resources\Target $x): bool $predicate, array $options = null) + * @method-extended \Nesk\Puphpeteer\Resources\Target target() + * @method \Nesk\Puphpeteer\Resources\Target waitForTarget(\Nesk\Rialto\Data\JsFunction $predicate, array $options = []) + * @method-extended \Nesk\Puphpeteer\Resources\Target waitForTarget(callable(\Nesk\Puphpeteer\Resources\Target $x): bool|\Nesk\Rialto\Data\JsFunction $predicate, array $options = null) * @method \Nesk\Puphpeteer\Resources\Page[] pages() + * @method-extended \Nesk\Puphpeteer\Resources\Page[] pages() * @method string version() + * @method-extended string version() * @method string userAgent() + * @method-extended string userAgent() * @method void close() + * @method-extended void close() * @method void disconnect() + * @method-extended void disconnect() * @method bool isConnected() + * @method-extended bool isConnected() */ class Browser extends EventEmitter { diff --git a/src/Resources/BrowserContext.php b/src/Resources/BrowserContext.php index faca430..abe2d6d 100644 --- a/src/Resources/BrowserContext.php +++ b/src/Resources/BrowserContext.php @@ -4,14 +4,23 @@ /** * @method \Nesk\Puphpeteer\Resources\Target[] targets() - * @method \Nesk\Puphpeteer\Resources\Target waitForTarget(callable(\Nesk\Puphpeteer\Resources\Target $x): bool $predicate, array{ timeout: float } $options = null) + * @method-extended \Nesk\Puphpeteer\Resources\Target[] targets() + * @method \Nesk\Puphpeteer\Resources\Target waitForTarget(\Nesk\Rialto\Data\JsFunction $predicate, array $options = []) + * @method-extended \Nesk\Puphpeteer\Resources\Target waitForTarget(callable(\Nesk\Puphpeteer\Resources\Target $x): bool|\Nesk\Rialto\Data\JsFunction $predicate, array{ timeout: float } $options = null) * @method \Nesk\Puphpeteer\Resources\Page[] pages() + * @method-extended \Nesk\Puphpeteer\Resources\Page[] pages() * @method bool isIncognito() + * @method-extended bool isIncognito() * @method void overridePermissions(string $origin, string[] $permissions) + * @method-extended void overridePermissions(string $origin, string[] $permissions) * @method void clearPermissionOverrides() + * @method-extended void clearPermissionOverrides() * @method \Nesk\Puphpeteer\Resources\Page newPage() + * @method-extended \Nesk\Puphpeteer\Resources\Page newPage() * @method \Nesk\Puphpeteer\Resources\Browser browser() + * @method-extended \Nesk\Puphpeteer\Resources\Browser browser() * @method void close() + * @method-extended void close() */ class BrowserContext extends EventEmitter { diff --git a/src/Resources/BrowserFetcher.php b/src/Resources/BrowserFetcher.php index 19f67cd..d6118d8 100644 --- a/src/Resources/BrowserFetcher.php +++ b/src/Resources/BrowserFetcher.php @@ -6,13 +6,21 @@ /** * @method mixed platform() + * @method-extended mixed platform() * @method mixed product() + * @method-extended mixed product() * @method string host() + * @method-extended string host() * @method bool canDownload(string $revision) - * @method mixed download(string $revision, callable(float $x, float $y): void $progressCallback = null) + * @method-extended bool canDownload(string $revision) + * @method mixed download(string $revision, \Nesk\Rialto\Data\JsFunction $progressCallback = null) + * @method-extended mixed download(string $revision, callable(float $x, float $y): void|\Nesk\Rialto\Data\JsFunction $progressCallback = null) * @method string[] localRevisions() + * @method-extended string[] localRevisions() * @method void remove(string $revision) + * @method-extended void remove(string $revision) * @method mixed revisionInfo(string $revision) + * @method-extended mixed revisionInfo(string $revision) */ class BrowserFetcher extends BasicResource { diff --git a/src/Resources/CDPSession.php b/src/Resources/CDPSession.php index 4983013..3fe0cab 100644 --- a/src/Resources/CDPSession.php +++ b/src/Resources/CDPSession.php @@ -4,7 +4,9 @@ /** * @method mixed send(mixed $method, mixed ...$paramArgs) + * @method-extended mixed send(mixed $method, mixed ...$paramArgs) * @method void detach() + * @method-extended void detach() */ class CDPSession extends EventEmitter { diff --git a/src/Resources/ConsoleMessage.php b/src/Resources/ConsoleMessage.php index 86b0b48..772ce05 100644 --- a/src/Resources/ConsoleMessage.php +++ b/src/Resources/ConsoleMessage.php @@ -6,10 +6,15 @@ /** * @method mixed type() + * @method-extended mixed type() * @method string text() + * @method-extended string text() * @method \Nesk\Puphpeteer\Resources\JSHandle[] args() + * @method-extended \Nesk\Puphpeteer\Resources\JSHandle[] args() * @method mixed location() + * @method-extended mixed location() * @method mixed[] stackTrace() + * @method-extended mixed[] stackTrace() */ class ConsoleMessage extends BasicResource { diff --git a/src/Resources/Coverage.php b/src/Resources/Coverage.php index 33b8391..8ba7b83 100644 --- a/src/Resources/Coverage.php +++ b/src/Resources/Coverage.php @@ -5,10 +5,14 @@ use Nesk\Rialto\Data\BasicResource; /** - * @method void startJSCoverage(array $options = null) + * @method void startJSCoverage(array $options = []) + * @method-extended void startJSCoverage(array $options = null) * @method mixed[] stopJSCoverage() - * @method void startCSSCoverage(array $options = null) + * @method-extended mixed[] stopJSCoverage() + * @method void startCSSCoverage(array $options = []) + * @method-extended void startCSSCoverage(array $options = null) * @method mixed[] stopCSSCoverage() + * @method-extended mixed[] stopCSSCoverage() */ class Coverage extends BasicResource { diff --git a/src/Resources/Dialog.php b/src/Resources/Dialog.php index 59eb603..9bd85bc 100644 --- a/src/Resources/Dialog.php +++ b/src/Resources/Dialog.php @@ -6,10 +6,15 @@ /** * @method mixed type() + * @method-extended mixed type() * @method string message() + * @method-extended string message() * @method string defaultValue() + * @method-extended string defaultValue() * @method void accept(string $promptText = null) + * @method-extended void accept(string $promptText = null) * @method void dismiss() + * @method-extended void dismiss() */ class Dialog extends BasicResource { diff --git a/src/Resources/ElementHandle.php b/src/Resources/ElementHandle.php index a7618b9..58f0ca6 100644 --- a/src/Resources/ElementHandle.php +++ b/src/Resources/ElementHandle.php @@ -6,20 +6,34 @@ use Nesk\Puphpeteer\Traits\AliasesEvaluationMethods; /** - * @method \Nesk\Puphpeteer\Resources\ElementHandle|null asElement() + * @method \Nesk\Puphpeteer\Resources\ElementHandle|mixed[]|null asElement() + * @method-extended \Nesk\Puphpeteer\Resources\ElementHandle|mixed[]|null asElement() * @method \Nesk\Puphpeteer\Resources\Frame|null contentFrame() + * @method-extended \Nesk\Puphpeteer\Resources\Frame|null contentFrame() * @method void hover() - * @method void click(array $options = null) + * @method-extended void hover() + * @method void click(array $options = []) + * @method-extended void click(array $options = null) * @method string[] select(string ...$values) + * @method-extended string[] select(string ...$values) * @method void uploadFile(string ...$filePaths) + * @method-extended void uploadFile(string ...$filePaths) * @method void tap() + * @method-extended void tap() * @method void focus() - * @method void type(string $text, array{ delay: float } $options = null) - * @method void press(mixed $key, array $options = null) + * @method-extended void focus() + * @method void type(string $text, array $options = []) + * @method-extended void type(string $text, array{ delay: float } $options = null) + * @method void press(mixed $key, array $options = []) + * @method-extended void press(mixed $key, array $options = null) * @method mixed|null boundingBox() + * @method-extended mixed|null boundingBox() * @method mixed|null boxModel() - * @method string|mixed|null screenshot(array{ } $options = null) + * @method-extended mixed|null boxModel() + * @method string|mixed|null screenshot(array $options = []) + * @method-extended string|mixed|null screenshot(array{ } $options = null) * @method bool isIntersectingViewport() + * @method-extended bool isIntersectingViewport() */ class ElementHandle extends JSHandle { diff --git a/src/Resources/EventEmitter.php b/src/Resources/EventEmitter.php index 180460c..5111ead 100644 --- a/src/Resources/EventEmitter.php +++ b/src/Resources/EventEmitter.php @@ -6,13 +6,21 @@ /** * @method \Nesk\Puphpeteer\Resources\EventEmitter on(mixed $event, mixed $handler) + * @method-extended \Nesk\Puphpeteer\Resources\EventEmitter on(mixed $event, mixed $handler) * @method \Nesk\Puphpeteer\Resources\EventEmitter off(mixed $event, mixed $handler) + * @method-extended \Nesk\Puphpeteer\Resources\EventEmitter off(mixed $event, mixed $handler) * @method \Nesk\Puphpeteer\Resources\EventEmitter removeListener(mixed $event, mixed $handler) + * @method-extended \Nesk\Puphpeteer\Resources\EventEmitter removeListener(mixed $event, mixed $handler) * @method \Nesk\Puphpeteer\Resources\EventEmitter addListener(mixed $event, mixed $handler) + * @method-extended \Nesk\Puphpeteer\Resources\EventEmitter addListener(mixed $event, mixed $handler) * @method bool emit(mixed $event, mixed $eventData = null) + * @method-extended bool emit(mixed $event, mixed $eventData = null) * @method \Nesk\Puphpeteer\Resources\EventEmitter once(mixed $event, mixed $handler) + * @method-extended \Nesk\Puphpeteer\Resources\EventEmitter once(mixed $event, mixed $handler) * @method float listenerCount(mixed $event) + * @method-extended float listenerCount(mixed $event) * @method \Nesk\Puphpeteer\Resources\EventEmitter removeAllListeners(mixed $event = null) + * @method-extended \Nesk\Puphpeteer\Resources\EventEmitter removeAllListeners(mixed $event = null) */ class EventEmitter extends BasicResource { diff --git a/src/Resources/ExecutionContext.php b/src/Resources/ExecutionContext.php index f506b22..3f94745 100644 --- a/src/Resources/ExecutionContext.php +++ b/src/Resources/ExecutionContext.php @@ -6,9 +6,13 @@ /** * @method \Nesk\Puphpeteer\Resources\Frame|null frame() - * @method mixed evaluate(callable|string $pageFunction, mixed ...$args) - * @method \Nesk\Puphpeteer\Resources\JSHandle|\Nesk\Puphpeteer\Resources\ElementHandle evaluateHandle(callable|string $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended \Nesk\Puphpeteer\Resources\Frame|null frame() + * @method mixed evaluate(\Nesk\Rialto\Data\JsFunction|string $pageFunction, mixed ...$args) + * @method-extended mixed evaluate(callable|\Nesk\Rialto\Data\JsFunction|string $pageFunction, mixed ...$args) + * @method \Nesk\Puphpeteer\Resources\JSHandle|\Nesk\Puphpeteer\Resources\ElementHandle evaluateHandle(\Nesk\Rialto\Data\JsFunction|string $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended \Nesk\Puphpeteer\Resources\JSHandle|\Nesk\Puphpeteer\Resources\ElementHandle evaluateHandle(\Nesk\Rialto\Data\JsFunction|callable|string $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) * @method \Nesk\Puphpeteer\Resources\JSHandle queryObjects(\Nesk\Puphpeteer\Resources\JSHandle $prototypeHandle) + * @method-extended \Nesk\Puphpeteer\Resources\JSHandle queryObjects(\Nesk\Puphpeteer\Resources\JSHandle $prototypeHandle) */ class ExecutionContext extends BasicResource { diff --git a/src/Resources/FileChooser.php b/src/Resources/FileChooser.php index b0b5cf3..3a08758 100644 --- a/src/Resources/FileChooser.php +++ b/src/Resources/FileChooser.php @@ -6,8 +6,11 @@ /** * @method bool isMultiple() + * @method-extended bool isMultiple() * @method void accept(string[] $filePaths) + * @method-extended void accept(string[] $filePaths) * @method void cancel() + * @method-extended void cancel() */ class FileChooser extends BasicResource { diff --git a/src/Resources/Frame.php b/src/Resources/Frame.php index 87948a4..3e83634 100644 --- a/src/Resources/Frame.php +++ b/src/Resources/Frame.php @@ -7,32 +7,58 @@ use Nesk\Puphpeteer\Traits\AliasesEvaluationMethods; /** - * @method \Nesk\Puphpeteer\Resources\HTTPResponse|null goto(string $url, array{ referer: string, timeout: float, waitUntil: string|string[] } $options = null) - * @method \Nesk\Puphpeteer\Resources\HTTPResponse|null waitForNavigation(array{ timeout: float, waitUntil: string|string[] } $options = null) + * @method \Nesk\Puphpeteer\Resources\HTTPResponse|null goto(string $url, array $options = []) + * @method-extended \Nesk\Puphpeteer\Resources\HTTPResponse|null goto(string $url, array{ referer: string, timeout: float, waitUntil: string|string[] } $options = null) + * @method \Nesk\Puphpeteer\Resources\HTTPResponse|null waitForNavigation(array $options = []) + * @method-extended \Nesk\Puphpeteer\Resources\HTTPResponse|null waitForNavigation(array{ timeout: float, waitUntil: string|string[] } $options = null) * @method \Nesk\Puphpeteer\Resources\ExecutionContext executionContext() - * @method mixed evaluateHandle(callable|string $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) - * @method mixed evaluate(mixed $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended \Nesk\Puphpeteer\Resources\ExecutionContext executionContext() + * @method mixed evaluateHandle(\Nesk\Rialto\Data\JsFunction|string $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended mixed evaluateHandle(\Nesk\Rialto\Data\JsFunction|callable|string $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method mixed evaluate(\Nesk\Rialto\Data\JsFunction $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended mixed evaluate(callable|\Nesk\Rialto\Data\JsFunction $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) * @method string content() - * @method void setContent(string $html, array{ timeout: float, waitUntil: string|string[] } $options = null) + * @method-extended string content() + * @method void setContent(string $html, array $options = []) + * @method-extended void setContent(string $html, array{ timeout: float, waitUntil: string|string[] } $options = null) * @method string name() + * @method-extended string name() * @method string url() + * @method-extended string url() * @method \Nesk\Puphpeteer\Resources\Frame|null parentFrame() + * @method-extended \Nesk\Puphpeteer\Resources\Frame|null parentFrame() * @method \Nesk\Puphpeteer\Resources\Frame[] childFrames() + * @method-extended \Nesk\Puphpeteer\Resources\Frame[] childFrames() * @method bool isDetached() - * @method \Nesk\Puphpeteer\Resources\ElementHandle addScriptTag(array $options) - * @method \Nesk\Puphpeteer\Resources\ElementHandle addStyleTag(array $options) - * @method void click(string $selector, array{ delay: float, button: mixed, clickCount: float } $options = null) + * @method-extended bool isDetached() + * @method \Nesk\Puphpeteer\Resources\ElementHandle addScriptTag(array $options) + * @method-extended \Nesk\Puphpeteer\Resources\ElementHandle addScriptTag(array $options) + * @method \Nesk\Puphpeteer\Resources\ElementHandle addStyleTag(array $options) + * @method-extended \Nesk\Puphpeteer\Resources\ElementHandle addStyleTag(array $options) + * @method void click(string $selector, array $options = []) + * @method-extended void click(string $selector, array{ delay: float, button: mixed, clickCount: float } $options = null) * @method void focus(string $selector) + * @method-extended void focus(string $selector) * @method void hover(string $selector) + * @method-extended void hover(string $selector) * @method string[] select(string $selector, string ...$values) + * @method-extended string[] select(string $selector, string ...$values) * @method void tap(string $selector) - * @method void type(string $selector, string $text, array{ delay: float } $options = null) - * @method \Nesk\Puphpeteer\Resources\JSHandle|null waitFor(string|float|callable $selectorOrFunctionOrTimeout, array $options = null, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended void tap(string $selector) + * @method void type(string $selector, string $text, array $options = []) + * @method-extended void type(string $selector, string $text, array{ delay: float } $options = null) + * @method \Nesk\Puphpeteer\Resources\JSHandle|null waitFor(string|float|\Nesk\Rialto\Data\JsFunction $selectorOrFunctionOrTimeout, array|string[]|mixed[] $options = null, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended \Nesk\Puphpeteer\Resources\JSHandle|null waitFor(string|float|callable|\Nesk\Rialto\Data\JsFunction $selectorOrFunctionOrTimeout, array|string[]|mixed[] $options = null, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) * @method void waitForTimeout(float $milliseconds) - * @method \Nesk\Puphpeteer\Resources\ElementHandle|null waitForSelector(string $selector, array $options = null) - * @method \Nesk\Puphpeteer\Resources\ElementHandle|null waitForXPath(string $xpath, array $options = null) - * @method \Nesk\Puphpeteer\Resources\JSHandle waitForFunction(callable|string $pageFunction, array $options = null, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended void waitForTimeout(float $milliseconds) + * @method \Nesk\Puphpeteer\Resources\ElementHandle|null waitForSelector(string $selector, array $options = []) + * @method-extended \Nesk\Puphpeteer\Resources\ElementHandle|null waitForSelector(string $selector, array $options = null) + * @method \Nesk\Puphpeteer\Resources\ElementHandle|null waitForXPath(string $xpath, array $options = []) + * @method-extended \Nesk\Puphpeteer\Resources\ElementHandle|null waitForXPath(string $xpath, array $options = null) + * @method \Nesk\Puphpeteer\Resources\JSHandle waitForFunction(\Nesk\Rialto\Data\JsFunction|string $pageFunction, array $options = [], int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended \Nesk\Puphpeteer\Resources\JSHandle waitForFunction(callable|\Nesk\Rialto\Data\JsFunction|string $pageFunction, array $options = null, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) * @method string title() + * @method-extended string title() */ class Frame extends BasicResource { diff --git a/src/Resources/HTTPRequest.php b/src/Resources/HTTPRequest.php index 7ce8558..94ed293 100644 --- a/src/Resources/HTTPRequest.php +++ b/src/Resources/HTTPRequest.php @@ -6,18 +6,31 @@ /** * @method string url() + * @method-extended string url() * @method string resourceType() + * @method-extended string resourceType() * @method string method() + * @method-extended string method() * @method string|null postData() - * @method array headers() + * @method-extended string|null postData() + * @method array|string[]|string[] headers() + * @method-extended array|string[]|string[] headers() * @method \Nesk\Puphpeteer\Resources\HTTPResponse|null response() + * @method-extended \Nesk\Puphpeteer\Resources\HTTPResponse|null response() * @method \Nesk\Puphpeteer\Resources\Frame|null frame() + * @method-extended \Nesk\Puphpeteer\Resources\Frame|null frame() * @method bool isNavigationRequest() + * @method-extended bool isNavigationRequest() * @method \Nesk\Puphpeteer\Resources\HTTPRequest[] redirectChain() - * @method array{ errorText: string }|null failure() + * @method-extended \Nesk\Puphpeteer\Resources\HTTPRequest[] redirectChain() + * @method array|null failure() + * @method-extended array{ errorText: string }|null failure() * @method void continue(mixed $overrides = null) + * @method-extended void continue(mixed $overrides = null) * @method void respond(mixed $response) + * @method-extended void respond(mixed $response) * @method void abort(mixed $errorCode = null) + * @method-extended void abort(mixed $errorCode = null) */ class HTTPRequest extends BasicResource { diff --git a/src/Resources/HTTPResponse.php b/src/Resources/HTTPResponse.php index d8b6ead..c8f6558 100644 --- a/src/Resources/HTTPResponse.php +++ b/src/Resources/HTTPResponse.php @@ -6,19 +6,33 @@ /** * @method mixed remoteAddress() + * @method-extended mixed remoteAddress() * @method string url() + * @method-extended string url() * @method bool ok() + * @method-extended bool ok() * @method float status() + * @method-extended float status() * @method string statusText() - * @method array headers() + * @method-extended string statusText() + * @method array|string[]|string[] headers() + * @method-extended array|string[]|string[] headers() * @method \Nesk\Puphpeteer\Resources\SecurityDetails|null securityDetails() + * @method-extended \Nesk\Puphpeteer\Resources\SecurityDetails|null securityDetails() * @method mixed buffer() + * @method-extended mixed buffer() * @method string text() + * @method-extended string text() * @method mixed json() + * @method-extended mixed json() * @method \Nesk\Puphpeteer\Resources\HTTPRequest request() + * @method-extended \Nesk\Puphpeteer\Resources\HTTPRequest request() * @method bool fromCache() + * @method-extended bool fromCache() * @method bool fromServiceWorker() + * @method-extended bool fromServiceWorker() * @method \Nesk\Puphpeteer\Resources\Frame|null frame() + * @method-extended \Nesk\Puphpeteer\Resources\Frame|null frame() */ class HTTPResponse extends BasicResource { diff --git a/src/Resources/JSHandle.php b/src/Resources/JSHandle.php index df9f357..9fe83d3 100644 --- a/src/Resources/JSHandle.php +++ b/src/Resources/JSHandle.php @@ -6,14 +6,23 @@ /** * @method \Nesk\Puphpeteer\Resources\ExecutionContext executionContext() - * @method mixed evaluate(mixed|string $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) - * @method \Nesk\Puphpeteer\Resources\JSHandle|\Nesk\Puphpeteer\Resources\ElementHandle evaluateHandle(callable|string $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended \Nesk\Puphpeteer\Resources\ExecutionContext executionContext() + * @method mixed evaluate(\Nesk\Rialto\Data\JsFunction $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended mixed evaluate(callable|\Nesk\Rialto\Data\JsFunction $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method \Nesk\Puphpeteer\Resources\JSHandle|\Nesk\Puphpeteer\Resources\ElementHandle evaluateHandle(\Nesk\Rialto\Data\JsFunction|string $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended \Nesk\Puphpeteer\Resources\JSHandle|\Nesk\Puphpeteer\Resources\ElementHandle evaluateHandle(\Nesk\Rialto\Data\JsFunction|callable|string $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) * @method \Nesk\Puphpeteer\Resources\JSHandle|null getProperty(string $propertyName) - * @method array getProperties() - * @method array jsonValue() + * @method-extended \Nesk\Puphpeteer\Resources\JSHandle|null getProperty(string $propertyName) + * @method array|string[]|\Nesk\Puphpeteer\Resources\JSHandle[] getProperties() + * @method-extended array|string[]|\Nesk\Puphpeteer\Resources\JSHandle[] getProperties() + * @method array|string[]|mixed[] jsonValue() + * @method-extended array|string[]|mixed[] jsonValue() * @method \Nesk\Puphpeteer\Resources\ElementHandle|null asElement() + * @method-extended \Nesk\Puphpeteer\Resources\ElementHandle|null asElement() * @method void dispose() + * @method-extended void dispose() * @method string toString() + * @method-extended string toString() */ class JSHandle extends BasicResource { diff --git a/src/Resources/Keyboard.php b/src/Resources/Keyboard.php index dd1ea96..62495c3 100644 --- a/src/Resources/Keyboard.php +++ b/src/Resources/Keyboard.php @@ -5,11 +5,16 @@ use Nesk\Rialto\Data\BasicResource; /** - * @method void down(mixed $key, array{ text: string } $options = null) + * @method void down(mixed $key, array $options = []) + * @method-extended void down(mixed $key, array{ text: string } $options = null) * @method void up(mixed $key) + * @method-extended void up(mixed $key) * @method void sendCharacter(string $char) - * @method void type(string $text, array{ delay: float } $options = null) - * @method void press(mixed $key, array{ delay: float, text: string } $options = null) + * @method-extended void sendCharacter(string $char) + * @method void type(string $text, array $options = []) + * @method-extended void type(string $text, array{ delay: float } $options = null) + * @method void press(mixed $key, array $options = []) + * @method-extended void press(mixed $key, array{ delay: float, text: string } $options = null) */ class Keyboard extends BasicResource { diff --git a/src/Resources/Mouse.php b/src/Resources/Mouse.php index c94afe1..967ace1 100644 --- a/src/Resources/Mouse.php +++ b/src/Resources/Mouse.php @@ -5,11 +5,16 @@ use Nesk\Rialto\Data\BasicResource; /** - * @method void move(float $x, float $y, array{ steps: float } $options = null) - * @method void click(float $x, float $y, array&array{ delay: float } $options = null) - * @method void down(array $options = null) - * @method void up(array $options = null) - * @method void wheel(array $options = null) + * @method void move(float $x, float $y, array $options = []) + * @method-extended void move(float $x, float $y, array{ steps: float } $options = null) + * @method void click(float $x, float $y, array $options = []) + * @method-extended void click(float $x, float $y, array&array{ delay: float } $options = null) + * @method void down(array $options = []) + * @method-extended void down(array $options = null) + * @method void up(array $options = []) + * @method-extended void up(array $options = null) + * @method void wheel(array $options = []) + * @method-extended void wheel(array $options = null) */ class Mouse extends BasicResource { diff --git a/src/Resources/Page.php b/src/Resources/Page.php index 9fe96d6..5c37b8a 100644 --- a/src/Resources/Page.php +++ b/src/Resources/Page.php @@ -13,70 +13,135 @@ * @property-read \Nesk\Puphpeteer\Resources\Accessibility accessibility * @property-read \Nesk\Puphpeteer\Resources\Mouse mouse * @method bool isJavaScriptEnabled() - * @method \Nesk\Puphpeteer\Resources\FileChooser waitForFileChooser(array $options = null) - * @method void setGeolocation(array $options) + * @method-extended bool isJavaScriptEnabled() + * @method \Nesk\Puphpeteer\Resources\FileChooser waitForFileChooser(array $options = []) + * @method-extended \Nesk\Puphpeteer\Resources\FileChooser waitForFileChooser(array $options = null) + * @method void setGeolocation(array $options) + * @method-extended void setGeolocation(array $options) * @method \Nesk\Puphpeteer\Resources\Target target() + * @method-extended \Nesk\Puphpeteer\Resources\Target target() * @method \Nesk\Puphpeteer\Resources\Browser browser() + * @method-extended \Nesk\Puphpeteer\Resources\Browser browser() * @method \Nesk\Puphpeteer\Resources\BrowserContext browserContext() + * @method-extended \Nesk\Puphpeteer\Resources\BrowserContext browserContext() * @method \Nesk\Puphpeteer\Resources\Frame mainFrame() + * @method-extended \Nesk\Puphpeteer\Resources\Frame mainFrame() * @method \Nesk\Puphpeteer\Resources\Frame[] frames() + * @method-extended \Nesk\Puphpeteer\Resources\Frame[] frames() * @method \Nesk\Puphpeteer\Resources\WebWorker[] workers() + * @method-extended \Nesk\Puphpeteer\Resources\WebWorker[] workers() * @method void setRequestInterception(bool $value) + * @method-extended void setRequestInterception(bool $value) * @method void setOfflineMode(bool $enabled) + * @method-extended void setOfflineMode(bool $enabled) * @method void setDefaultNavigationTimeout(float $timeout) + * @method-extended void setDefaultNavigationTimeout(float $timeout) * @method void setDefaultTimeout(float $timeout) - * @method mixed evaluateHandle(callable|string $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended void setDefaultTimeout(float $timeout) + * @method mixed evaluateHandle(\Nesk\Rialto\Data\JsFunction|string $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended mixed evaluateHandle(\Nesk\Rialto\Data\JsFunction|callable|string $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) * @method \Nesk\Puphpeteer\Resources\JSHandle queryObjects(\Nesk\Puphpeteer\Resources\JSHandle $prototypeHandle) + * @method-extended \Nesk\Puphpeteer\Resources\JSHandle queryObjects(\Nesk\Puphpeteer\Resources\JSHandle $prototypeHandle) * @method mixed[] cookies(string ...$urls) + * @method-extended mixed[] cookies(string ...$urls) * @method void deleteCookie(mixed ...$cookies) + * @method-extended void deleteCookie(mixed ...$cookies) * @method void setCookie(mixed ...$cookies) - * @method \Nesk\Puphpeteer\Resources\ElementHandle addScriptTag(array{ url: string, path: string, content: string, type: string } $options) - * @method \Nesk\Puphpeteer\Resources\ElementHandle addStyleTag(array{ url: string, path: string, content: string } $options) - * @method void exposeFunction(string $name, callable $puppeteerFunction) + * @method-extended void setCookie(mixed ...$cookies) + * @method \Nesk\Puphpeteer\Resources\ElementHandle addScriptTag(array $options) + * @method-extended \Nesk\Puphpeteer\Resources\ElementHandle addScriptTag(array{ url: string, path: string, content: string, type: string } $options) + * @method \Nesk\Puphpeteer\Resources\ElementHandle addStyleTag(array $options) + * @method-extended \Nesk\Puphpeteer\Resources\ElementHandle addStyleTag(array{ url: string, path: string, content: string } $options) + * @method void exposeFunction(string $name, \Nesk\Rialto\Data\JsFunction $puppeteerFunction) + * @method-extended void exposeFunction(string $name, callable|\Nesk\Rialto\Data\JsFunction $puppeteerFunction) * @method void authenticate(mixed $credentials) - * @method void setExtraHTTPHeaders(array $headers) + * @method-extended void authenticate(mixed $credentials) + * @method void setExtraHTTPHeaders(array|string[]|string[] $headers) + * @method-extended void setExtraHTTPHeaders(array|string[]|string[] $headers) * @method void setUserAgent(string $userAgent) + * @method-extended void setUserAgent(string $userAgent) * @method mixed metrics() + * @method-extended mixed metrics() * @method string url() + * @method-extended string url() * @method string content() - * @method void setContent(string $html, array $options = null) - * @method \Nesk\Puphpeteer\Resources\HTTPResponse goto(string $url, array&array{ referer: string } $options = null) - * @method \Nesk\Puphpeteer\Resources\HTTPResponse|null reload(array $options = null) - * @method \Nesk\Puphpeteer\Resources\HTTPResponse|null waitForNavigation(array $options = null) - * @method \Nesk\Puphpeteer\Resources\HTTPRequest waitForRequest(string|callable $urlOrPredicate, array{ timeout: float } $options = null) - * @method \Nesk\Puphpeteer\Resources\HTTPResponse waitForResponse(string|callable $urlOrPredicate, array{ timeout: float } $options = null) - * @method \Nesk\Puphpeteer\Resources\HTTPResponse|null goBack(array $options = null) - * @method \Nesk\Puphpeteer\Resources\HTTPResponse|null goForward(array $options = null) + * @method-extended string content() + * @method void setContent(string $html, array $options = []) + * @method-extended void setContent(string $html, array $options = null) + * @method \Nesk\Puphpeteer\Resources\HTTPResponse goto(string $url, array $options = []) + * @method-extended \Nesk\Puphpeteer\Resources\HTTPResponse goto(string $url, array&array{ referer: string } $options = null) + * @method \Nesk\Puphpeteer\Resources\HTTPResponse|null reload(array $options = []) + * @method-extended \Nesk\Puphpeteer\Resources\HTTPResponse|null reload(array $options = null) + * @method \Nesk\Puphpeteer\Resources\HTTPResponse|null waitForNavigation(array $options = []) + * @method-extended \Nesk\Puphpeteer\Resources\HTTPResponse|null waitForNavigation(array $options = null) + * @method \Nesk\Puphpeteer\Resources\HTTPRequest waitForRequest(string|\Nesk\Rialto\Data\JsFunction $urlOrPredicate, array $options = []) + * @method-extended \Nesk\Puphpeteer\Resources\HTTPRequest waitForRequest(string|callable|\Nesk\Rialto\Data\JsFunction $urlOrPredicate, array{ timeout: float } $options = null) + * @method \Nesk\Puphpeteer\Resources\HTTPResponse waitForResponse(string|\Nesk\Rialto\Data\JsFunction $urlOrPredicate, array $options = []) + * @method-extended \Nesk\Puphpeteer\Resources\HTTPResponse waitForResponse(string|callable|\Nesk\Rialto\Data\JsFunction $urlOrPredicate, array{ timeout: float } $options = null) + * @method \Nesk\Puphpeteer\Resources\HTTPResponse|null goBack(array $options = []) + * @method-extended \Nesk\Puphpeteer\Resources\HTTPResponse|null goBack(array $options = null) + * @method \Nesk\Puphpeteer\Resources\HTTPResponse|null goForward(array $options = []) + * @method-extended \Nesk\Puphpeteer\Resources\HTTPResponse|null goForward(array $options = null) * @method void bringToFront() - * @method void emulate(array{ viewport: mixed, userAgent: string } $options) + * @method-extended void bringToFront() + * @method void emulate(array $options) + * @method-extended void emulate(array{ viewport: mixed, userAgent: string } $options) * @method void setJavaScriptEnabled(bool $enabled) + * @method-extended void setJavaScriptEnabled(bool $enabled) * @method void setBypassCSP(bool $enabled) + * @method-extended void setBypassCSP(bool $enabled) * @method void emulateMediaType(string $type = null) + * @method-extended void emulateMediaType(string $type = null) * @method void emulateMediaFeatures(mixed[] $features = null) + * @method-extended void emulateMediaFeatures(mixed[] $features = null) * @method void emulateTimezone(string $timezoneId = null) - * @method void emulateIdleState(array{ isUserActive: bool, isScreenUnlocked: bool } $overrides = null) + * @method-extended void emulateTimezone(string $timezoneId = null) + * @method void emulateIdleState(array $overrides = []) + * @method-extended void emulateIdleState(array{ isUserActive: bool, isScreenUnlocked: bool } $overrides = null) * @method void emulateVisionDeficiency(mixed $type = null) + * @method-extended void emulateVisionDeficiency(mixed $type = null) * @method void setViewport(mixed $viewport) + * @method-extended void setViewport(mixed $viewport) * @method mixed|null viewport() - * @method mixed evaluate(mixed $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) - * @method void evaluateOnNewDocument(callable|string $pageFunction, mixed ...$args) + * @method-extended mixed|null viewport() + * @method mixed evaluate(\Nesk\Rialto\Data\JsFunction $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended mixed evaluate(callable|\Nesk\Rialto\Data\JsFunction $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method void evaluateOnNewDocument(\Nesk\Rialto\Data\JsFunction|string $pageFunction, mixed ...$args) + * @method-extended void evaluateOnNewDocument(callable|\Nesk\Rialto\Data\JsFunction|string $pageFunction, mixed ...$args) * @method void setCacheEnabled(bool $enabled = null) - * @method mixed|string|null screenshot(array $options = null) - * @method mixed pdf(array $options = null) + * @method-extended void setCacheEnabled(bool $enabled = null) + * @method mixed|string|null screenshot(array $options = []) + * @method-extended mixed|string|null screenshot(array $options = null) + * @method mixed pdf(array $options = []) + * @method-extended mixed pdf(array $options = null) * @method string title() - * @method void close(array{ runBeforeUnload: bool } $options = null) + * @method-extended string title() + * @method void close(array $options = []) + * @method-extended void close(array{ runBeforeUnload: bool } $options = null) * @method bool isClosed() - * @method void click(string $selector, array{ delay: float, button: mixed, clickCount: float } $options = null) + * @method-extended bool isClosed() + * @method void click(string $selector, array $options = []) + * @method-extended void click(string $selector, array{ delay: float, button: mixed, clickCount: float } $options = null) * @method void focus(string $selector) + * @method-extended void focus(string $selector) * @method void hover(string $selector) + * @method-extended void hover(string $selector) * @method string[] select(string $selector, string ...$values) + * @method-extended string[] select(string $selector, string ...$values) * @method void tap(string $selector) - * @method void type(string $selector, string $text, array{ delay: float } $options = null) - * @method \Nesk\Puphpeteer\Resources\JSHandle waitFor(string|float|callable $selectorOrFunctionOrTimeout, array{ visible: bool, hidden: bool, timeout: float, polling: string|float } $options = null, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended void tap(string $selector) + * @method void type(string $selector, string $text, array $options = []) + * @method-extended void type(string $selector, string $text, array{ delay: float } $options = null) + * @method \Nesk\Puphpeteer\Resources\JSHandle waitFor(string|float|\Nesk\Rialto\Data\JsFunction $selectorOrFunctionOrTimeout, array $options = [], int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended \Nesk\Puphpeteer\Resources\JSHandle waitFor(string|float|callable|\Nesk\Rialto\Data\JsFunction $selectorOrFunctionOrTimeout, array{ visible: bool, hidden: bool, timeout: float, polling: string|float } $options = null, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) * @method void waitForTimeout(float $milliseconds) - * @method \Nesk\Puphpeteer\Resources\ElementHandle|null waitForSelector(string $selector, array{ visible: bool, hidden: bool, timeout: float } $options = null) - * @method \Nesk\Puphpeteer\Resources\ElementHandle|null waitForXPath(string $xpath, array{ visible: bool, hidden: bool, timeout: float } $options = null) - * @method \Nesk\Puphpeteer\Resources\JSHandle waitForFunction(callable|string $pageFunction, array{ timeout: float, polling: string|float } $options = null, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended void waitForTimeout(float $milliseconds) + * @method \Nesk\Puphpeteer\Resources\ElementHandle|null waitForSelector(string $selector, array $options = []) + * @method-extended \Nesk\Puphpeteer\Resources\ElementHandle|null waitForSelector(string $selector, array{ visible: bool, hidden: bool, timeout: float } $options = null) + * @method \Nesk\Puphpeteer\Resources\ElementHandle|null waitForXPath(string $xpath, array $options = []) + * @method-extended \Nesk\Puphpeteer\Resources\ElementHandle|null waitForXPath(string $xpath, array{ visible: bool, hidden: bool, timeout: float } $options = null) + * @method \Nesk\Puphpeteer\Resources\JSHandle waitForFunction(\Nesk\Rialto\Data\JsFunction|string $pageFunction, array $options = [], int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended \Nesk\Puphpeteer\Resources\JSHandle waitForFunction(callable|\Nesk\Rialto\Data\JsFunction|string $pageFunction, array{ timeout: float, polling: string|float } $options = null, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) */ class Page extends EventEmitter { diff --git a/src/Resources/SecurityDetails.php b/src/Resources/SecurityDetails.php index 2b40242..a041ef3 100644 --- a/src/Resources/SecurityDetails.php +++ b/src/Resources/SecurityDetails.php @@ -6,11 +6,17 @@ /** * @method string issuer() + * @method-extended string issuer() * @method float validFrom() + * @method-extended float validFrom() * @method float validTo() + * @method-extended float validTo() * @method string protocol() + * @method-extended string protocol() * @method string subjectName() + * @method-extended string subjectName() * @method string[] subjectAlternativeNames() + * @method-extended string[] subjectAlternativeNames() */ class SecurityDetails extends BasicResource { diff --git a/src/Resources/Target.php b/src/Resources/Target.php index 0a51543..0f8fd82 100644 --- a/src/Resources/Target.php +++ b/src/Resources/Target.php @@ -6,13 +6,21 @@ /** * @method \Nesk\Puphpeteer\Resources\CDPSession createCDPSession() + * @method-extended \Nesk\Puphpeteer\Resources\CDPSession createCDPSession() * @method \Nesk\Puphpeteer\Resources\Page|null page() + * @method-extended \Nesk\Puphpeteer\Resources\Page|null page() * @method \Nesk\Puphpeteer\Resources\WebWorker|null worker() + * @method-extended \Nesk\Puphpeteer\Resources\WebWorker|null worker() * @method string url() + * @method-extended string url() * @method string type() + * @method-extended string type() * @method \Nesk\Puphpeteer\Resources\Browser browser() + * @method-extended \Nesk\Puphpeteer\Resources\Browser browser() * @method \Nesk\Puphpeteer\Resources\BrowserContext browserContext() + * @method-extended \Nesk\Puphpeteer\Resources\BrowserContext browserContext() * @method \Nesk\Puphpeteer\Resources\Target|null opener() + * @method-extended \Nesk\Puphpeteer\Resources\Target|null opener() */ class Target extends BasicResource { diff --git a/src/Resources/Touchscreen.php b/src/Resources/Touchscreen.php index 80bae89..077a716 100644 --- a/src/Resources/Touchscreen.php +++ b/src/Resources/Touchscreen.php @@ -6,6 +6,7 @@ /** * @method void tap(float $x, float $y) + * @method-extended void tap(float $x, float $y) */ class Touchscreen extends BasicResource { diff --git a/src/Resources/Tracing.php b/src/Resources/Tracing.php index 6cc364d..f54ceab 100644 --- a/src/Resources/Tracing.php +++ b/src/Resources/Tracing.php @@ -5,8 +5,10 @@ use Nesk\Rialto\Data\BasicResource; /** - * @method void start(array $options = null) + * @method void start(array $options = []) + * @method-extended void start(array $options = null) * @method mixed stop() + * @method-extended mixed stop() */ class Tracing extends BasicResource { diff --git a/src/Resources/WebWorker.php b/src/Resources/WebWorker.php index 764ebe7..691c9f2 100644 --- a/src/Resources/WebWorker.php +++ b/src/Resources/WebWorker.php @@ -6,9 +6,13 @@ /** * @method string url() + * @method-extended string url() * @method \Nesk\Puphpeteer\Resources\ExecutionContext executionContext() - * @method mixed evaluate(callable|string $pageFunction, mixed ...$args) - * @method \Nesk\Puphpeteer\Resources\JSHandle evaluateHandle(callable|string $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended \Nesk\Puphpeteer\Resources\ExecutionContext executionContext() + * @method mixed evaluate(\Nesk\Rialto\Data\JsFunction|string $pageFunction, mixed ...$args) + * @method-extended mixed evaluate(callable|\Nesk\Rialto\Data\JsFunction|string $pageFunction, mixed ...$args) + * @method \Nesk\Puphpeteer\Resources\JSHandle evaluateHandle(\Nesk\Rialto\Data\JsFunction|string $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) + * @method-extended \Nesk\Puphpeteer\Resources\JSHandle evaluateHandle(\Nesk\Rialto\Data\JsFunction|callable|string $pageFunction, int|float|string|bool|null|array|\Nesk\Puphpeteer\Resources\JSHandle ...$args) */ class WebWorker extends BasicResource { diff --git a/src/Traits/AliasesEvaluationMethods.php b/src/Traits/AliasesEvaluationMethods.php index fe29882..2496abe 100644 --- a/src/Traits/AliasesEvaluationMethods.php +++ b/src/Traits/AliasesEvaluationMethods.php @@ -2,11 +2,12 @@ namespace Nesk\Puphpeteer\Traits; +use Nesk\Puphpeteer\Resources\JSHandle; use Nesk\Rialto\Data\JsFunction; /** - * @method bool|int|float|string|array|null querySelectorEval(string $selector, JsFunction $pageFunction, bool|int|float|string|array|null|JSHandle ...args) - * @method bool|int|float|string|array|null querySelectorAllEval(string $selector, JsFunction $pageFunction, bool|int|float|string|array|null|JSHandle ...args) + * @method bool|int|float|string|array|null querySelectorEval(string $selector, JsFunction $pageFunction, bool|int|float|string|array|null|JSHandle ...$args) + * @method bool|int|float|string|array|null querySelectorAllEval(string $selector, JsFunction $pageFunction, bool|int|float|string|array|null|JSHandle ...$args) */ trait AliasesEvaluationMethods { diff --git a/src/Traits/AliasesSelectionMethods.php b/src/Traits/AliasesSelectionMethods.php index 22d4380..3217e32 100644 --- a/src/Traits/AliasesSelectionMethods.php +++ b/src/Traits/AliasesSelectionMethods.php @@ -2,10 +2,12 @@ namespace Nesk\Puphpeteer\Traits; +use Nesk\Puphpeteer\Resources\ElementHandle; + /** * @method ElementHandle|null querySelector(string $selector) - * @method array querySelectorAll(string $selector) - * @method array querySelectorXPath(string $expression) + * @method ElementHandle[] querySelectorAll(string $selector) + * @method ElementHandle[] querySelectorXPath(string $expression) */ trait AliasesSelectionMethods { diff --git a/src/doc-generator.ts b/src/doc-generator.ts index 0c133e7..c3f6da8 100644 --- a/src/doc-generator.ts +++ b/src/doc-generator.ts @@ -1,6 +1,7 @@ import * as ts from 'typescript'; const yargs = require('yargs/yargs'); const { hideBin } = require('yargs/helpers'); +const callbackClass = '\\Nesk\\Rialto\\Data\\JsFunction'; type ObjectMemberAsJson = { [key: string]: string; } @@ -155,8 +156,8 @@ class PhpDocumentationFormatter implements DocumentationFormatter { static readonly allowedJsClasses = ['Promise', 'Record', 'Map']; constructor( - private readonly resourcesNamespace: string, - private readonly resources: string[], + protected readonly resourcesNamespace: string, + protected readonly resources: string[], ) {} formatProperty(name: string, type: string, context: MemberContext): string { @@ -170,7 +171,7 @@ class PhpDocumentationFormatter implements DocumentationFormatter { } formatAnonymousFunction(parameters: string, returnType: string): string { - return `callable(${parameters}): ${returnType}`; + return callbackClass; } formatFunction(name: string, parameters: string, returnType: string): string { @@ -182,7 +183,17 @@ class PhpDocumentationFormatter implements DocumentationFormatter { type = type.slice(0, -2); } - const defaultValue = isOptional ? ' = null' : ''; + let defaultValue; + + switch (type) { + case 'array' : + defaultValue = isOptional ? ' = []' : ''; + break; + default: + defaultValue = isOptional ? ' = null' : ''; + break; + } + return `${type} ${isVariadic ? '...' : ''}\$${name}${defaultValue}`; } @@ -226,21 +237,21 @@ class PhpDocumentationFormatter implements DocumentationFormatter { // Prefix PHP resources with their namespace if (this.resources.includes(type)) { - return `\\${this.resourcesNamespace}\\${type}`; + return this.resourcesNamespace ? `\\${this.resourcesNamespace}\\${type}` : type; } // If the type ends with "options" then convert it to an associative array if (/options$/i.test(type)) { - return 'array'; + return 'array'; } // Types ending with "Fn" are always callables or strings if (type.endsWith('Fn')) { - return this.formatUnion(['callable', 'string']); + return this.formatUnion([callbackClass, 'string']); } if (type === 'Function') { - return 'callable'; + return callbackClass; } if (type === 'PuppeteerLifeCycleEvent') { @@ -278,7 +289,7 @@ class PhpDocumentationFormatter implements DocumentationFormatter { parentType = 'array'; } - return `${parentType}<${argumentTypes.join(', ')}>`; + return `${parentType}|${argumentTypes.join('[]|')}[]`; } formatQualifiedName(left: string, right: string): string { @@ -318,7 +329,7 @@ class PhpDocumentationFormatter implements DocumentationFormatter { } formatObject(members: string[]): string { - return `array{ ${members.join(', ')} }`; + return `array`; } formatArray(type: string): string { @@ -326,6 +337,60 @@ class PhpDocumentationFormatter implements DocumentationFormatter { } } +class PhpStanDocumentationFormatter extends PhpDocumentationFormatter { + formatAnonymousFunction(parameters: string, returnType: string): string { + return `callable(${parameters}): ${returnType}|` + callbackClass; + } + + formatTypeReference(type: string): string { + // Allow some specific JS classes to be used in phpDoc + if (PhpDocumentationFormatter.allowedJsClasses.includes(type)) { + return type; + } + + // Prefix PHP resources with their namespace + if (this.resources.includes(type)) { + return this.resourcesNamespace ? `\\${this.resourcesNamespace}\\${type}` : type; + } + + // If the type ends with "options" then convert it to an associative array + if (/options$/i.test(type)) { + return 'array'; + } + + // Types ending with "Fn" are always callables or strings + if (type.endsWith('Fn')) { + return this.formatUnion([callbackClass, 'callable', 'string']); + } + + if (type === 'Function') { + return this.formatUnion(['callable', callbackClass]); + } + + if (type === 'PuppeteerLifeCycleEvent') { + return 'string'; + } + + if (type === 'Serializable') { + return this.formatUnion(['int', 'float', 'string', 'bool', 'null', 'array']); + } + + if (type === 'SerializableOrJSHandle') { + return this.formatUnion([this.formatTypeReference('Serializable'), this.formatTypeReference('JSHandle')]); + } + + if (type === 'HandleType') { + return this.formatUnion([this.formatTypeReference('JSHandle'), this.formatTypeReference('ElementHandle')]); + } + + return 'mixed'; + } + + formatObject(members: string[]): string { + return `array{ ${members.join(', ')} }`; + } +} + class DocumentationGenerator { constructor( private readonly supportChecker: SupportChecker, @@ -345,7 +410,7 @@ class DocumentationGenerator { private isNodeAccessible(node: ts.Node): boolean { // @ts-ignore - if (node.name && this.getNamedDeclarationAsString(node).startsWith('_')) { + if (node.name && (this.getNamedDeclarationAsString(node).startsWith('_') || this.getNamedDeclarationAsString(node).startsWith('#'))) { return false; } @@ -428,11 +493,23 @@ class DocumentationGenerator { : this.formatter.formatAnonymousFunction(parameters, returnType); } + private getEmptyFunctionSignatureAsString( + node: ts.ParenthesizedTypeNode + ): string { + return this.formatter.formatAnonymousFunction(this.getTypeNodeAsString(node.type), ''); + } + private getParameterDeclarationAsString(node: ts.ParameterDeclaration): string { const name = this.getNamedDeclarationAsString(node); - const type = this.getTypeNodeAsString(node.type); + let type = this.getTypeNodeAsString(node.type); const isVariadic = node.dotDotDotToken !== undefined; const isOptional = node.questionToken !== undefined; + + //fix missing argument type in evaluate* methods. + if (name.includes('Function') && type.includes('mixed')) { + type = this.formatter.formatTypeReference('Function'); + } + return this.formatter.formatParameter(name, type, isVariadic, isOptional); } @@ -469,6 +546,8 @@ class DocumentationGenerator { return this.getArrayTypeNodeAsString(node, context); } else if (ts.isFunctionTypeNode(node)) { return this.getSignatureDeclarationBaseAsString(node); + } else if (ts.isParenthesizedTypeNode(node)) { + return this.getEmptyFunctionSignatureAsString(node); } else { throw new TypeNotSupportedError(); } @@ -545,13 +624,13 @@ class DocumentationGenerator { } private getNamedDeclarationAsString(node: ts.NamedDeclaration): string { - if (!ts.isIdentifier(node.name)) { + if (!ts.isIdentifier(node.name) && !ts.isPrivateIdentifier(node.name)) { throw new TypeNotSupportedError(); } return this.getIdentifierAsString(node.name); } - private getIdentifierAsString(node: ts.Identifier): string { + private getIdentifierAsString(node: ts.Identifier|ts.PrivateIdentifier): string { return String(node.escapedText); } } @@ -572,6 +651,10 @@ switch (argv.language.toUpperCase()) { supportChecker = new PhpSupportChecker(); formatter = new PhpDocumentationFormatter(argv.resourcesNamespace, argv.resources); break; + case 'PHPSTAN': + supportChecker = new PhpSupportChecker(); + formatter = new PhpStanDocumentationFormatter(argv.resourcesNamespace, argv.resources); + break; default: console.error(`Unsupported "${argv.language}" language.`); process.exit(1);