Multiple fixes
* Implemented ScriptRunner with environment expansion and cleaner code. * Added ApiClient plugin (com.noccy.apiclient) * Renamed CHANGELOG.md to VERSIONS.md * Shuffled buildtools * Added first unittests
This commit is contained in:
		
							
								
								
									
										91
									
								
								plugins/com.noccy.apiclient/Commands/ApiCatalogCommand.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								plugins/com.noccy.apiclient/Commands/ApiCatalogCommand.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace SparkPlug\Com\Noccy\ApiClient\Commands;
 | 
			
		||||
 | 
			
		||||
use Spark\Commands\Command;
 | 
			
		||||
use SparkPlug;
 | 
			
		||||
use SparkPlug\Com\Noccy\ApiClient\Api\Catalog;
 | 
			
		||||
use Symfony\Component\Console\Input\InputArgument;
 | 
			
		||||
use Symfony\Component\Console\Input\InputInterface;
 | 
			
		||||
use Symfony\Component\Console\Input\InputOption;
 | 
			
		||||
use Symfony\Component\Console\Output\OutputInterface;
 | 
			
		||||
 | 
			
		||||
class ApiCatalogCommand extends Command
 | 
			
		||||
{
 | 
			
		||||
    protected function configure()
 | 
			
		||||
    {
 | 
			
		||||
        $this->setName("api:catalog")
 | 
			
		||||
            ->setDescription("Manage the API catalogs")
 | 
			
		||||
            ->addOption("create", "c", InputOption::VALUE_REQUIRED, "Create a new catalog")
 | 
			
		||||
            ->addOption("remove", "r", InputOption::VALUE_REQUIRED, "Remove a catalog")
 | 
			
		||||
            ->addOption("set-props", null, InputOption::VALUE_REQUIRED, "Apply properties to a catalog")
 | 
			
		||||
            ->addArgument("properties", InputArgument::IS_ARRAY, "Default properties for the catalog")
 | 
			
		||||
            ->addOption("list", null, InputOption::VALUE_NONE, "Only list catalogs, not methods")
 | 
			
		||||
            ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function execute(InputInterface $input, OutputInterface $output)
 | 
			
		||||
    {
 | 
			
		||||
        $api = get_plugin('com.noccy.apiclient');
 | 
			
		||||
        $list = $input->getOption("list");
 | 
			
		||||
        $dest = get_environment()->getConfigDirectory() . "/api/catalogs";
 | 
			
		||||
 | 
			
		||||
        if ($create = $input->getOption("create")) {
 | 
			
		||||
            if (file_exists($dest."/".$create.".json")) {
 | 
			
		||||
                $output->writeln("<error>Catalog {$create} already exists!</>");
 | 
			
		||||
                return Command::FAILURE;
 | 
			
		||||
            }
 | 
			
		||||
            $catalog = new Catalog([
 | 
			
		||||
                'catalog' => [
 | 
			
		||||
                    'name' => $create
 | 
			
		||||
                ]
 | 
			
		||||
            ]);
 | 
			
		||||
            file_put_contents($dest."/".$create.".json", json_encode($catalog, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
 | 
			
		||||
            $output->writeln("<info>Created new catalog {$create}</>");
 | 
			
		||||
            return Command::SUCCESS;
 | 
			
		||||
        } 
 | 
			
		||||
        if ($remove = $input->getOption("remove")) {
 | 
			
		||||
            if (!file_exists($dest."/".$remove.".json")) {
 | 
			
		||||
                $output->writeln("<error>Catalog {$remove} does not exist!</>");
 | 
			
		||||
                return Command::FAILURE;
 | 
			
		||||
            }
 | 
			
		||||
            unlink($dest."/".$remove.".json");
 | 
			
		||||
            $output->writeln("<info>Removed catalog {$remove}</>");
 | 
			
		||||
            return Command::SUCCESS;
 | 
			
		||||
        }
 | 
			
		||||
        if ($setprops = $input->getOption("set-props")) {
 | 
			
		||||
            $proparr = [];
 | 
			
		||||
            $props = $input->getArgument("properties");
 | 
			
		||||
            foreach ($props as $str) {
 | 
			
		||||
                if (!str_contains($str,"=")) {
 | 
			
		||||
                    $output->writeln("<error>Ignoring parameter argument '{$str}'</>");
 | 
			
		||||
                } else {
 | 
			
		||||
                    [$k,$v] = explode("=",$str,2);
 | 
			
		||||
                    $proparr[$k] = $v;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            $catalog = $api->getCatalog($setprops);
 | 
			
		||||
            $catalog->applyProperties($proparr);
 | 
			
		||||
            $api->saveCatalog($catalog);
 | 
			
		||||
            $output->writeln("<info>Updated properties on catalog {$setprops}</>");
 | 
			
		||||
            return Command::SUCCESS;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $catalogs = $api->getCatalogNames();
 | 
			
		||||
        foreach ($catalogs as $catalog) {
 | 
			
		||||
            $c = $api->getCatalog($catalog);
 | 
			
		||||
            if ($list) {
 | 
			
		||||
                $output->writeln($catalog);
 | 
			
		||||
            } else {
 | 
			
		||||
                $output->writeln("\u{25e9} <options=bold>{$catalog}</>: <fg=gray>{$c->getInfo()}</>");
 | 
			
		||||
                $ms = $c->getMethods();
 | 
			
		||||
                foreach ($ms as $name=>$m) {
 | 
			
		||||
                    $last = ($m === end($ms));
 | 
			
		||||
                    $output->writeln(($last?"\u{2514}\u{2500}":"\u{251c}\u{2500}")."\u{25a2} {$catalog}.{$name}: <info>{$m->getInfo()}</>");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return Command::SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								plugins/com.noccy.apiclient/Commands/ApiLogsCommand.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								plugins/com.noccy.apiclient/Commands/ApiLogsCommand.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace SparkPlug\Com\Noccy\ApiClient\Commands;
 | 
			
		||||
 | 
			
		||||
use Spark\Commands\Command;
 | 
			
		||||
use SparkPlug;
 | 
			
		||||
use SparkPlug\Com\Noccy\ApiClient\Api\Method;
 | 
			
		||||
use SparkPlug\Com\Noccy\ApiClient\ApiClientPlugin;
 | 
			
		||||
use SparkPlug\Com\Noccy\ApiClient\Request\RequestBuilder;
 | 
			
		||||
use Symfony\Component\Console\Helper\Table;
 | 
			
		||||
use Symfony\Component\Console\Input\InputArgument;
 | 
			
		||||
use Symfony\Component\Console\Input\InputInterface;
 | 
			
		||||
use Symfony\Component\Console\Input\InputOption;
 | 
			
		||||
use Symfony\Component\Console\Output\OutputInterface;
 | 
			
		||||
 | 
			
		||||
class ApiLogsCommand extends Command
 | 
			
		||||
{
 | 
			
		||||
    protected function configure()
 | 
			
		||||
    {
 | 
			
		||||
        $this->setName("api:logs")
 | 
			
		||||
            ->setDescription("Show previous requests and manage the log")
 | 
			
		||||
            ->addOption("clear", null, InputOption::VALUE_NONE, "Clear the log")
 | 
			
		||||
            ->addOption("write", "w", InputOption::VALUE_REQUIRED, "Write the formatted entries to a file")
 | 
			
		||||
            ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function execute(InputInterface $input, OutputInterface $output)
 | 
			
		||||
    {
 | 
			
		||||
        /** @var ApiClientPlugin */
 | 
			
		||||
        $plugin = get_plugin('com.noccy.apiclient');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        return Command::SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								plugins/com.noccy.apiclient/Commands/ApiProfileCommand.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								plugins/com.noccy.apiclient/Commands/ApiProfileCommand.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace SparkPlug\Com\Noccy\ApiClient\Commands;
 | 
			
		||||
 | 
			
		||||
use Spark\Commands\Command;
 | 
			
		||||
use SparkPlug;
 | 
			
		||||
use Symfony\Component\Console\Input\InputInterface;
 | 
			
		||||
use Symfony\Component\Console\Output\OutputInterface;
 | 
			
		||||
 | 
			
		||||
class ApiProfileCommand extends Command
 | 
			
		||||
{
 | 
			
		||||
    protected function configure()
 | 
			
		||||
    {
 | 
			
		||||
        $this->setName("api:profile")
 | 
			
		||||
            ->setDescription("Manage API profiles");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function execute(InputInterface $input, OutputInterface $output)
 | 
			
		||||
    {
 | 
			
		||||
        return Command::SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										134
									
								
								plugins/com.noccy.apiclient/Commands/ApiRequestCommand.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								plugins/com.noccy.apiclient/Commands/ApiRequestCommand.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,134 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace SparkPlug\Com\Noccy\ApiClient\Commands;
 | 
			
		||||
 | 
			
		||||
use Spark\Commands\Command;
 | 
			
		||||
use SparkPlug;
 | 
			
		||||
use SparkPlug\Com\Noccy\ApiClient\Api\Method;
 | 
			
		||||
use SparkPlug\Com\Noccy\ApiClient\ApiClientPlugin;
 | 
			
		||||
use SparkPlug\Com\Noccy\ApiClient\Request\RequestBuilder;
 | 
			
		||||
use Symfony\Component\Console\Helper\Table;
 | 
			
		||||
use Symfony\Component\Console\Input\InputArgument;
 | 
			
		||||
use Symfony\Component\Console\Input\InputInterface;
 | 
			
		||||
use Symfony\Component\Console\Input\InputOption;
 | 
			
		||||
use Symfony\Component\Console\Output\OutputInterface;
 | 
			
		||||
 | 
			
		||||
class ApiRequestCommand extends Command
 | 
			
		||||
{
 | 
			
		||||
    protected function configure()
 | 
			
		||||
    {
 | 
			
		||||
        $this->setName("api:request")
 | 
			
		||||
            ->setDescription("Send a request")
 | 
			
		||||
            ->addOption("profile", "p", InputOption::VALUE_REQUIRED, "Use profile for request")
 | 
			
		||||
            ->addOption("save", "s", InputOption::VALUE_NONE, "Save to catalog")
 | 
			
		||||
            ->addArgument("method", InputArgument::OPTIONAL, "Request URL or catalog.method")
 | 
			
		||||
            ->addArgument("props", InputArgument::IS_ARRAY, "Parameter key=value pairs")
 | 
			
		||||
            ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function execute(InputInterface $input, OutputInterface $output)
 | 
			
		||||
    {
 | 
			
		||||
        /** @var ApiClientPlugin */
 | 
			
		||||
        $plugin = get_plugin('com.noccy.apiclient');
 | 
			
		||||
 | 
			
		||||
        $separator = str_repeat("\u{2500}", 40);
 | 
			
		||||
 | 
			
		||||
        $method = $input->getArgument("method");
 | 
			
		||||
        $builder = new RequestBuilder();
 | 
			
		||||
        if (str_contains($method, "://")) {
 | 
			
		||||
            $builder->setProperties([
 | 
			
		||||
                'url' => $method
 | 
			
		||||
            ]);
 | 
			
		||||
        } else {
 | 
			
		||||
            if (str_contains($method, '.')) {
 | 
			
		||||
                [$catalog,$method] = explode(".", $method, 2);
 | 
			
		||||
                $catalogObj = $plugin->getCatalog($catalog);
 | 
			
		||||
                // if (!$catalogObj) {
 | 
			
		||||
                //     $output->writeln("<error>No such catalog {$catalog}</>");
 | 
			
		||||
                //     return Command::FAILURE;
 | 
			
		||||
                // }
 | 
			
		||||
                $methodObj = $catalogObj->getMethod($method);
 | 
			
		||||
                // if (!$methodObj) {
 | 
			
		||||
                //     $output->writeln("<error>No such method {$method} in catalog {$catalog}</>");
 | 
			
		||||
                //     return Command::FAILURE;
 | 
			
		||||
                // }
 | 
			
		||||
                $builder->setCatalog($catalogObj);
 | 
			
		||||
                $builder->setMethod($methodObj);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        $props = [];
 | 
			
		||||
        $propstr = $input->getArgument("props");
 | 
			
		||||
        foreach ($propstr as $str) {
 | 
			
		||||
            if (!str_contains($str,"=")) {
 | 
			
		||||
                $output->writeln("<error>Ignoring parameter argument '{$str}'</>");
 | 
			
		||||
            } else {
 | 
			
		||||
                [$k,$v] = explode("=",$str,2);
 | 
			
		||||
                $props[$k] = $v;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        $builder->addProperties($props);
 | 
			
		||||
 | 
			
		||||
        if ($input->getOption("save")) {
 | 
			
		||||
            $catalogObj = $plugin->getCatalog($catalog);
 | 
			
		||||
            $methodObj = new Method([
 | 
			
		||||
                'name' => $method,
 | 
			
		||||
                'info' => $props['method.info']??null,
 | 
			
		||||
                'props' => $props
 | 
			
		||||
            ]);
 | 
			
		||||
            
 | 
			
		||||
            $catalogObj->addMethod($method, $methodObj);
 | 
			
		||||
            $plugin->saveCatalog($catalogObj);
 | 
			
		||||
            $output->writeln("<info>Saved method {$method} to catalog {$catalog}</>");
 | 
			
		||||
            return self::SUCCESS;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($profile = $input->getOption("profile")) {
 | 
			
		||||
            $profileObj = $plugin->getProfile($profile);
 | 
			
		||||
            $builder->setProfile($profileObj);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $request = $builder->getRequest();
 | 
			
		||||
 | 
			
		||||
        $table = new Table($output);
 | 
			
		||||
        $table->setStyle('compact');
 | 
			
		||||
        $table->setHeaders([ "Request Info", "" ]);
 | 
			
		||||
        foreach ($request->getInfo() as $i=>$v) {
 | 
			
		||||
            $table->addRow([$i,$v]);
 | 
			
		||||
        }
 | 
			
		||||
        $table->render();
 | 
			
		||||
 | 
			
		||||
        $table = new Table($output);
 | 
			
		||||
        $table->setStyle('compact');
 | 
			
		||||
        $table->setHeaders([ "Request Headers", "" ]);
 | 
			
		||||
        foreach ($request->getHeaders() as $i=>$v) {
 | 
			
		||||
            $table->addRow([$i,join("\n",$v)]);
 | 
			
		||||
        }
 | 
			
		||||
        $table->render();
 | 
			
		||||
 | 
			
		||||
        $output->writeln($separator);
 | 
			
		||||
        $response = $request->send();
 | 
			
		||||
        
 | 
			
		||||
        $rheaders = $response->getHeaders();
 | 
			
		||||
        $table = new Table($output);
 | 
			
		||||
        $table->setStyle('compact');
 | 
			
		||||
        $table->setHeaders([ "Response headers", "" ]);
 | 
			
		||||
        foreach ($rheaders as $h=>$v) {
 | 
			
		||||
            $table->addRow([$h,join("\n",$v)]);
 | 
			
		||||
        }
 | 
			
		||||
        $table->render();
 | 
			
		||||
        $body = (string)$response->getBody();
 | 
			
		||||
        $output->writeln($separator);
 | 
			
		||||
 | 
			
		||||
        $parseAs = $builder->getCalculatedProperty('response.parse');
 | 
			
		||||
        if ($parseAs == 'json') {
 | 
			
		||||
            dump(json_decode($body));
 | 
			
		||||
        } else {
 | 
			
		||||
            $output->writeln($body);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $output->writeln($separator);
 | 
			
		||||
        $output->writeln(strlen($body)." bytes");
 | 
			
		||||
 | 
			
		||||
        return Command::SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user