Introducing settings file, some refactorings and stabilization
This commit is contained in:
@@ -5,21 +5,19 @@ declare(strict_types=1);
|
||||
namespace PmConverter\Converters\Abstract;
|
||||
|
||||
use Exception;
|
||||
use Iterator;
|
||||
use PmConverter\Collection;
|
||||
use PmConverter\Converters\{
|
||||
ConverterContract,
|
||||
RequestContract};
|
||||
use PmConverter\Converters\RequestContract;
|
||||
use PmConverter\Environment;
|
||||
use PmConverter\Exceptions\{
|
||||
CannotCreateDirectoryException,
|
||||
DirectoryIsNotWriteableException,
|
||||
InvalidHttpVersionException};
|
||||
use PmConverter\Exceptions\CannotCreateDirectoryException;
|
||||
use PmConverter\Exceptions\DirectoryIsNotWriteableException;
|
||||
use PmConverter\Exceptions\InvalidHttpVersionException;
|
||||
use PmConverter\FileSystem;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
abstract class AbstractConverter implements ConverterContract
|
||||
abstract class AbstractConverter
|
||||
{
|
||||
/**
|
||||
* @var Collection|null
|
||||
@@ -32,53 +30,66 @@ abstract class AbstractConverter implements ConverterContract
|
||||
protected string $outputPath;
|
||||
|
||||
/**
|
||||
* @var Environment|null
|
||||
* @var RequestContract[] Converted requests
|
||||
*/
|
||||
protected ?Environment $env = null;
|
||||
protected array $requests = [];
|
||||
|
||||
/**
|
||||
* Sets an environment with vars
|
||||
* Sets output path
|
||||
*
|
||||
* @param Environment $env
|
||||
* @param string $outputPath
|
||||
* @return $this
|
||||
*/
|
||||
public function withEnv(Environment $env): static
|
||||
public function to(string $outputPath): self
|
||||
{
|
||||
$this->env = $env;
|
||||
$this->outputPath = sprintf('%s%s%s', $outputPath, DS, static::OUTPUT_DIR);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new directory to save a converted collection into
|
||||
*
|
||||
* @param string $outputPath
|
||||
* @return void
|
||||
* @throws CannotCreateDirectoryException
|
||||
* @throws DirectoryIsNotWriteableException
|
||||
*/
|
||||
protected function prepareOutputDir(string $outputPath): void
|
||||
{
|
||||
$outputPath = sprintf('%s%s%s', $outputPath, DS, static::OUTPUT_DIR);
|
||||
$this->outputPath = FileSystem::makeDir($outputPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts collection requests
|
||||
* Converts requests from collection
|
||||
*
|
||||
* @param Collection $collection
|
||||
* @param string $outputPath
|
||||
* @return void
|
||||
* @return static
|
||||
* @throws CannotCreateDirectoryException
|
||||
* @throws DirectoryIsNotWriteableException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function convert(Collection $collection, string $outputPath): void
|
||||
public function convert(Collection $collection): static
|
||||
{
|
||||
$this->prepareOutputDir($outputPath);
|
||||
$this->collection = $collection;
|
||||
$this->setVariables();
|
||||
foreach ($collection->item as $item) {
|
||||
$this->convertItem($item);
|
||||
$this->outputPath = FileSystem::makeDir($this->outputPath);
|
||||
$this->setCollectionVars();
|
||||
foreach ($collection->iterate() as $path => $item) {
|
||||
// $this->requests[$path][] = $this->makeRequest($item);
|
||||
$this->writeRequest($this->makeRequest($item), $path);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns converted requests
|
||||
*
|
||||
* @return Iterator<string, RequestContract>
|
||||
*/
|
||||
public function converted(): Iterator
|
||||
{
|
||||
foreach ($this->requests as $path => $requests) {
|
||||
foreach ($requests as $request) {
|
||||
yield $path => $request;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes requests on disk
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function flush(): void
|
||||
{
|
||||
foreach ($this->converted() as $path => $request) {
|
||||
$this->writeRequest($request, $path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,13 +98,10 @@ abstract class AbstractConverter implements ConverterContract
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function setVariables(): static
|
||||
protected function setCollectionVars(): static
|
||||
{
|
||||
empty($this->env) && $this->env = new Environment($this->collection?->variable);
|
||||
if (!empty($this->collection?->variable)) {
|
||||
foreach ($this->collection->variable as $var) {
|
||||
$this->env[$var->key] = $var->value;
|
||||
}
|
||||
foreach ($this->collection?->variable ?? [] as $var) {
|
||||
Environment::instance()->setCustomVar($var->key, $var->value);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
@@ -121,30 +129,6 @@ abstract class AbstractConverter implements ConverterContract
|
||||
&& empty($item->request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an item to request object and writes it into file
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function convertItem(mixed $item): void
|
||||
{
|
||||
if ($this->isItemFolder($item)) {
|
||||
static $dir_tree;
|
||||
foreach ($item->item as $subitem) {
|
||||
$dir_tree[] = $item->name;
|
||||
$path = implode(DS, $dir_tree);
|
||||
if ($this->isItemFolder($subitem)) {
|
||||
$this->convertItem($subitem);
|
||||
} else {
|
||||
$this->writeRequest($this->initRequest($subitem), $path);
|
||||
}
|
||||
array_pop($dir_tree);
|
||||
}
|
||||
} else {
|
||||
$this->writeRequest($this->initRequest($item));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialiazes request object to be written in file
|
||||
*
|
||||
@@ -152,17 +136,18 @@ abstract class AbstractConverter implements ConverterContract
|
||||
* @return RequestContract
|
||||
* @throws InvalidHttpVersionException
|
||||
*/
|
||||
protected function initRequest(object $item): RequestContract
|
||||
protected function makeRequest(object $item): RequestContract
|
||||
{
|
||||
$request_class = static::REQUEST_CLASS;
|
||||
|
||||
/** @var RequestContract $request */
|
||||
$request = new $request_class();
|
||||
$request->setName($item->name);
|
||||
$request->setVersion($this->collection->version);
|
||||
$request->setHttpVersion(1.1); //TODO http version?
|
||||
$request->setDescription($item->request?->description ?? null);
|
||||
$request->setVerb($item->request->method);
|
||||
$request->setUrl($item->request->url->raw);
|
||||
$request->setUrl($item->request->url);
|
||||
$request->setHeaders($item->request->header);
|
||||
$request->setAuth($item->request?->auth ?? $this->collection?->auth ?? null);
|
||||
if ($item->request->method !== 'GET' && !empty($item->request->body)) {
|
||||
@@ -196,18 +181,9 @@ abstract class AbstractConverter implements ConverterContract
|
||||
*/
|
||||
protected function interpolate(string $content): string
|
||||
{
|
||||
if (!$this->env?->hasVars()) {
|
||||
return $content;
|
||||
}
|
||||
$matches = [];
|
||||
if (preg_match_all('/\{\{.*}}/m', $content, $matches, PREG_PATTERN_ORDER) > 0) {
|
||||
foreach ($matches[0] as $key => $var) {
|
||||
if (str_contains($content, $var)) {
|
||||
$content = str_replace($var, $this->env[$var] ?: $var, $content);
|
||||
unset($matches[0][$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $content;
|
||||
$replace = static fn ($a) => Environment::instance()->var($var = $a[0]) ?: $var;
|
||||
return Environment::instance()->hasVars()
|
||||
? preg_replace_callback('/\{\{.*}}/m', $replace, $content)
|
||||
: $content;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Converters\Abstract;
|
||||
|
||||
use PmConverter\CollectionVersion;
|
||||
use PmConverter\Converters\RequestContract;
|
||||
use PmConverter\Exceptions\{
|
||||
EmptyHttpVerbException,
|
||||
InvalidHttpVersionException};
|
||||
use PmConverter\Exceptions\EmptyHttpVerbException;
|
||||
use PmConverter\Exceptions\InvalidHttpVersionException;
|
||||
use PmConverter\HttpVersion;
|
||||
use Stringable;
|
||||
|
||||
@@ -22,9 +22,9 @@ abstract class AbstractRequest implements Stringable, RequestContract
|
||||
protected string $verb;
|
||||
|
||||
/**
|
||||
* @var string URL where to send a request
|
||||
* @var object|string URL where to send a request
|
||||
*/
|
||||
protected string $url;
|
||||
protected object|string $url;
|
||||
|
||||
/**
|
||||
* @var float HTTP protocol version
|
||||
@@ -56,6 +56,15 @@ abstract class AbstractRequest implements Stringable, RequestContract
|
||||
*/
|
||||
protected string $bodymode = 'raw';
|
||||
|
||||
|
||||
protected CollectionVersion $version;
|
||||
|
||||
public function setVersion(CollectionVersion $version): static
|
||||
{
|
||||
$this->version = $version;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@@ -133,7 +142,7 @@ abstract class AbstractRequest implements Stringable, RequestContract
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setUrl(string $url): static
|
||||
public function setUrl(object|string $url): static
|
||||
{
|
||||
$this->url = $url;
|
||||
return $this;
|
||||
@@ -142,9 +151,9 @@ abstract class AbstractRequest implements Stringable, RequestContract
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getUrl(): string
|
||||
public function getRawUrl(): string
|
||||
{
|
||||
return $this->url ?: '<empty url>';
|
||||
return is_object($this->url) ? $this->url->raw : $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,7 +195,11 @@ abstract class AbstractRequest implements Stringable, RequestContract
|
||||
if (!empty($auth)) {
|
||||
switch ($auth->type) {
|
||||
case 'bearer':
|
||||
$this->setHeader('Authorization', 'Bearer ' . $auth->{$auth->type}[0]->value);
|
||||
$this->setHeader('Authorization', 'Bearer ' . match ($this->version) {
|
||||
CollectionVersion::Version20 => $auth->{$auth->type}->token,
|
||||
CollectionVersion::Version21 => $auth->{$auth->type}[0]->value,
|
||||
default => null
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -5,12 +5,11 @@ declare(strict_types=1);
|
||||
namespace PmConverter\Converters;
|
||||
|
||||
|
||||
use PmConverter\Converters\{
|
||||
Curl\CurlConverter,
|
||||
Http\HttpConverter,
|
||||
Postman20\Postman20Converter,
|
||||
Postman21\Postman21Converter,
|
||||
Wget\WgetConverter};
|
||||
use PmConverter\Converters\Curl\CurlConverter;
|
||||
use PmConverter\Converters\Http\HttpConverter;
|
||||
use PmConverter\Converters\Postman20\Postman20Converter;
|
||||
use PmConverter\Converters\Postman21\Postman21Converter;
|
||||
use PmConverter\Converters\Wget\WgetConverter;
|
||||
|
||||
enum ConvertFormat: string
|
||||
{
|
||||
@@ -19,4 +18,26 @@ enum ConvertFormat: string
|
||||
case Wget = WgetConverter::class;
|
||||
case Postman20 = Postman20Converter::class;
|
||||
case Postman21 = Postman21Converter::class;
|
||||
|
||||
public static function fromArg(string $arg): self
|
||||
{
|
||||
return match ($arg) {
|
||||
'http' => ConvertFormat::Http,
|
||||
'curl' => ConvertFormat::Curl,
|
||||
'wget' => ConvertFormat::Wget,
|
||||
'v2.0' => ConvertFormat::Postman20,
|
||||
'v2.1' => ConvertFormat::Postman21,
|
||||
};
|
||||
}
|
||||
|
||||
public function toArg(): string
|
||||
{
|
||||
return match ($this) {
|
||||
ConvertFormat::Http => 'http',
|
||||
ConvertFormat::Curl => 'curl',
|
||||
ConvertFormat::Wget => 'wget',
|
||||
ConvertFormat::Postman20 => 'v2.0',
|
||||
ConvertFormat::Postman21 => 'v2.1',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Converters\Curl;
|
||||
|
||||
use PmConverter\Converters\{
|
||||
Abstract\AbstractConverter,
|
||||
ConverterContract};
|
||||
use PmConverter\Converters\Abstract\AbstractConverter;
|
||||
|
||||
class CurlConverter extends AbstractConverter implements ConverterContract
|
||||
class CurlConverter extends AbstractConverter
|
||||
{
|
||||
protected const FILE_EXT = 'sh';
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ class CurlRequest extends AbstractRequest
|
||||
"curl \ ",
|
||||
"\t--http1.1 \ ", //TODO proto
|
||||
"\t--request $this->verb \ ",
|
||||
"\t--location $this->url \ ",
|
||||
"\t--location {$this->getRawUrl()} \ ",
|
||||
],
|
||||
$this->prepareHeaders(),
|
||||
$this->prepareBody()
|
||||
|
||||
@@ -4,11 +4,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Converters\Http;
|
||||
|
||||
use PmConverter\Converters\{
|
||||
Abstract\AbstractConverter,
|
||||
ConverterContract};
|
||||
use PmConverter\Converters\Abstract\AbstractConverter;
|
||||
|
||||
class HttpConverter extends AbstractConverter implements ConverterContract
|
||||
class HttpConverter extends AbstractConverter
|
||||
{
|
||||
protected const FILE_EXT = 'http';
|
||||
|
||||
|
||||
@@ -5,8 +5,7 @@ declare(strict_types=1);
|
||||
namespace PmConverter\Converters\Http;
|
||||
|
||||
use PmConverter\Converters\Abstract\AbstractRequest;
|
||||
use PmConverter\Exceptions\{
|
||||
EmptyHttpVerbException};
|
||||
use PmConverter\Exceptions\EmptyHttpVerbException;
|
||||
|
||||
/**
|
||||
* Class to determine file content with http request format
|
||||
@@ -29,7 +28,7 @@ class HttpRequest extends AbstractRequest
|
||||
*/
|
||||
protected function prepareHeaders(): array
|
||||
{
|
||||
$output[] = sprintf('%s %s HTTP/%s', $this->getVerb(), $this->getUrl(), $this->getHttpVersion());
|
||||
$output[] = sprintf('%s %s HTTP/%s', $this->getVerb(), $this->getRawUrl(), $this->getHttpVersion());
|
||||
foreach ($this->headers as $name => $data) {
|
||||
$output[] = sprintf('%s%s: %s', $data['disabled'] ? '# ' : '', $name, $data['value']);
|
||||
}
|
||||
|
||||
@@ -6,9 +6,7 @@ namespace PmConverter\Converters\Postman20;
|
||||
|
||||
use PmConverter\Collection;
|
||||
use PmConverter\CollectionVersion;
|
||||
use PmConverter\Converters\{
|
||||
Abstract\AbstractConverter,
|
||||
ConverterContract};
|
||||
use PmConverter\Converters\Abstract\AbstractConverter;
|
||||
use PmConverter\Exceptions\CannotCreateDirectoryException;
|
||||
use PmConverter\Exceptions\DirectoryIsNotWriteableException;
|
||||
use PmConverter\FileSystem;
|
||||
@@ -16,7 +14,7 @@ use PmConverter\FileSystem;
|
||||
/**
|
||||
* Converts Postman Collection v2.1 to v2.0
|
||||
*/
|
||||
class Postman20Converter extends AbstractConverter implements ConverterContract
|
||||
class Postman20Converter extends AbstractConverter
|
||||
{
|
||||
protected const FILE_EXT = 'v20.postman_collection.json';
|
||||
|
||||
@@ -26,25 +24,25 @@ class Postman20Converter extends AbstractConverter implements ConverterContract
|
||||
* Converts collection requests
|
||||
*
|
||||
* @param Collection $collection
|
||||
* @param string $outputPath
|
||||
* @return void
|
||||
* @return static
|
||||
* @throws CannotCreateDirectoryException
|
||||
* @throws DirectoryIsNotWriteableException
|
||||
*/
|
||||
public function convert(Collection $collection, string $outputPath): void
|
||||
public function convert(Collection $collection): static
|
||||
{
|
||||
$this->collection = $collection;
|
||||
// if data was exported from API, here is already valid json to
|
||||
// just flush it in file, otherwise we need to convert it deeper
|
||||
if ($this->collection->version() === CollectionVersion::Version21) {
|
||||
if ($this->collection->version === CollectionVersion::Version21) {
|
||||
$this->collection->info->schema = str_replace('/v2.1.', '/v2.0.', $this->collection->info->schema);
|
||||
$this->convertAuth($this->collection->raw());
|
||||
foreach ($this->collection->item as $item) {
|
||||
$this->convertItem($item);
|
||||
}
|
||||
}
|
||||
$this->prepareOutputDir($outputPath);
|
||||
$this->outputPath = FileSystem::makeDir($this->outputPath);
|
||||
$this->writeCollection();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,11 +95,11 @@ class Postman20Converter extends AbstractConverter implements ConverterContract
|
||||
if (empty($request->auth)) {
|
||||
return;
|
||||
}
|
||||
$type = $request->auth->type;
|
||||
if ($type !== 'noauth' && is_array($request->auth->$type)) {
|
||||
$auth = [];
|
||||
$auth = ['type' => 'noauth'];
|
||||
$type = strtolower($request->auth->type);
|
||||
if ($type !== 'noauth') {
|
||||
foreach ($request->auth->$type as $param) {
|
||||
$auth[$param->key] = $param->value;
|
||||
$auth[$param->key] = $param->value ?? '';
|
||||
}
|
||||
$request->auth->$type = (object)$auth;
|
||||
}
|
||||
|
||||
@@ -6,9 +6,7 @@ namespace PmConverter\Converters\Postman21;
|
||||
|
||||
use PmConverter\Collection;
|
||||
use PmConverter\CollectionVersion;
|
||||
use PmConverter\Converters\{
|
||||
Abstract\AbstractConverter,
|
||||
ConverterContract};
|
||||
use PmConverter\Converters\Abstract\AbstractConverter;
|
||||
use PmConverter\Exceptions\CannotCreateDirectoryException;
|
||||
use PmConverter\Exceptions\DirectoryIsNotWriteableException;
|
||||
use PmConverter\FileSystem;
|
||||
@@ -16,7 +14,7 @@ use PmConverter\FileSystem;
|
||||
/**
|
||||
* Converts Postman Collection v2.0 to v2.1
|
||||
*/
|
||||
class Postman21Converter extends AbstractConverter implements ConverterContract
|
||||
class Postman21Converter extends AbstractConverter
|
||||
{
|
||||
protected const FILE_EXT = 'v21.postman_collection.json';
|
||||
|
||||
@@ -26,25 +24,25 @@ class Postman21Converter extends AbstractConverter implements ConverterContract
|
||||
* Converts collection requests
|
||||
*
|
||||
* @param Collection $collection
|
||||
* @param string $outputPath
|
||||
* @return void
|
||||
* @return static
|
||||
* @throws CannotCreateDirectoryException
|
||||
* @throws DirectoryIsNotWriteableException
|
||||
*/
|
||||
public function convert(Collection $collection, string $outputPath): void
|
||||
public function convert(Collection $collection): static
|
||||
{
|
||||
$this->collection = $collection;
|
||||
// if data was exported from API, here is already valid json to
|
||||
// just flush it in file, otherwise we need to convert it deeper
|
||||
if ($this->collection->version() === CollectionVersion::Version20) {
|
||||
if ($this->collection->version === CollectionVersion::Version20) {
|
||||
$this->collection->info->schema = str_replace('/v2.0.', '/v2.1.', $this->collection->info->schema);
|
||||
$this->convertAuth($this->collection->raw());
|
||||
foreach ($this->collection->item as $item) {
|
||||
$this->convertItem($item);
|
||||
}
|
||||
}
|
||||
$this->prepareOutputDir($outputPath);
|
||||
$this->outputPath = FileSystem::makeDir($this->outputPath);
|
||||
$this->writeCollection();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -86,7 +86,7 @@ interface RequestContract
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl(): string;
|
||||
public function getRawUrl(): string;
|
||||
|
||||
/**
|
||||
* Sets headers from collection item to request object
|
||||
@@ -116,7 +116,7 @@ interface RequestContract
|
||||
/**
|
||||
* Sets authorization headers
|
||||
*
|
||||
* @param object|null $auth
|
||||
* @param object $auth
|
||||
* @return $this
|
||||
*/
|
||||
public function setAuth(object $auth): static;
|
||||
|
||||
@@ -4,11 +4,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Converters\Wget;
|
||||
|
||||
use PmConverter\Converters\{
|
||||
Abstract\AbstractConverter,
|
||||
ConverterContract};
|
||||
use PmConverter\Converters\Abstract\AbstractConverter;
|
||||
|
||||
class WgetConverter extends AbstractConverter implements ConverterContract
|
||||
class WgetConverter extends AbstractConverter
|
||||
{
|
||||
protected const FILE_EXT = 'sh';
|
||||
|
||||
|
||||
@@ -77,16 +77,16 @@ class WgetRequest extends AbstractRequest
|
||||
if ($this->getBodymode() === 'formdata') {
|
||||
if ($this->getBody()) {
|
||||
if ($this->getVerb() === 'GET') {
|
||||
$output[] = sprintf("\t%s?%s", $this->getUrl(), http_build_query($this->prepareBody()));
|
||||
$output[] = sprintf("\t%s?%s", $this->getRawUrl(), http_build_query($this->prepareBody()));
|
||||
} else {
|
||||
$output[] = sprintf("\t--body-data '%s' \ ", http_build_query($this->prepareBody()));
|
||||
$output[] = sprintf("\t%s", $this->getUrl());
|
||||
$output[] = sprintf("\t%s", $this->getRawUrl());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($this->getVerb() !== 'GET') {
|
||||
$output[] = sprintf("\t--body-data '%s' \ ", implode("\n", $this->prepareBody()));
|
||||
$output[] = sprintf("\t%s", $this->getUrl());
|
||||
$output[] = sprintf("\t%s", $this->getRawUrl());
|
||||
}
|
||||
}
|
||||
return implode(EOL, array_merge($output, ['']));
|
||||
|
||||
Reference in New Issue
Block a user