Initial and very naive conversion v2.0 => v2.1 (#10)

This commit is contained in:
Anthony Axenov 2023-09-17 23:59:37 +08:00
parent 3c1871ce1f
commit 01d29ee023
Signed by: anthony
GPG Key ID: EA9EC32FF7CCD4EC
7 changed files with 190 additions and 11 deletions

View File

@ -13,7 +13,8 @@
"keywords": ["postman", "collection", "converter", "http", "wget", "curl", "api", "convert"],
"require": {
"php": "^8.1",
"ext-json": "*"
"ext-json": "*",
"ext-mbstring": "*"
},
"bin": ["pm-convert"],
"autoload": {

View File

@ -12,6 +12,7 @@ use Stringable;
*
* @property array|object $item
* @property object $info
* @property object|null $variable
*/
class Collection implements Stringable
{

View File

@ -9,6 +9,7 @@ use PmConverter\Converters\{
Curl\CurlConverter,
Http\HttpConverter,
Postman20\Postman20Converter,
Postman21\Postman21Converter,
Wget\WgetConverter};
enum ConvertFormat: string
@ -17,4 +18,5 @@ enum ConvertFormat: string
case Curl = CurlConverter::class;
case Wget = WgetConverter::class;
case Postman20 = Postman20Converter::class;
case Postman21 = Postman21Converter::class;
}

View File

@ -19,7 +19,7 @@ class Postman20Converter extends AbstractConverter implements ConverterContract
{
protected const FILE_EXT = 'v20.postman_collection.json';
protected const OUTPUT_DIR = 'v2.0';
protected const OUTPUT_DIR = 'pm-v2.0';
/**
* Converts collection requests
@ -93,7 +93,7 @@ class Postman20Converter extends AbstractConverter implements ConverterContract
return;
}
$type = $request->auth->type;
if ($type !== 'noauth' && is_array($request->auth->$type)) { // bearer
if ($type !== 'noauth' && is_array($request->auth->$type)) {
$auth = [];
foreach ($request->auth->$type as $param) {
$auth[$param->key] = $param->value;
@ -125,8 +125,7 @@ class Postman20Converter extends AbstractConverter implements ConverterContract
{
foreach ($responses as $response) {
if (is_object($response->originalRequest->url)) {
$raw = $response->originalRequest->url->raw;
$response->originalRequest->url = $raw;
$response->originalRequest->url = $response->originalRequest->url->raw;
}
}
}

View File

@ -0,0 +1,164 @@
<?php
declare(strict_types=1);
namespace PmConverter\Converters\Postman21;
use PmConverter\Collection;
use PmConverter\Converters\{
Abstract\AbstractConverter,
ConverterContract};
use PmConverter\Exceptions\CannotCreateDirectoryException;
use PmConverter\Exceptions\DirectoryIsNotWriteableException;
use PmConverter\FileSystem;
/**
* Converts Postman Collection v2.0 to v2.1
*/
class Postman21Converter extends AbstractConverter implements ConverterContract
{
protected const FILE_EXT = 'v21.postman_collection.json';
protected const OUTPUT_DIR = 'pm-v2.1';
/**
* Converts collection requests
*
* @param Collection $collection
* @param string $outputPath
* @return void
* @throws CannotCreateDirectoryException
* @throws DirectoryIsNotWriteableException
*/
public function convert(Collection $collection, string $outputPath): void
{
$this->collection = $collection;
$this->collection->info->schema = str_replace('/v2.0.', '/v2.1.', $this->collection->info->schema);
$this->prepareOutputDir($outputPath);
$this->convertAuth($this->collection->raw());
foreach ($this->collection->item as $item) {
$this->convertItem($item);
}
$this->writeCollection();
}
/**
* Writes converted collection into file
*
* @return bool
* @throws CannotCreateDirectoryException
* @throws DirectoryIsNotWriteableException
*/
protected function writeCollection(): bool
{
$filedir = FileSystem::makeDir($this->outputPath);
$filepath = sprintf('%s%s%s.%s', $filedir, DIRECTORY_SEPARATOR, $this->collection->name(), static::FILE_EXT);
return file_put_contents($filepath, $this->collection) > 0;
}
/**
* Changes some requests fields in place
*
* @param mixed $item
* @return void
*/
protected function convertItem(mixed $item): void
{
if ($this->isItemFolder($item)) {
foreach ($item->item as $subitem) {
if ($this->isItemFolder($subitem)) {
$this->convertItem($subitem);
} else {
$this->convertAuth($subitem->request);
$this->convertRequestUrl($subitem->request);
$this->convertResponseUrls($subitem->response);
}
}
} else {
$this->convertAuth($item->request);
$this->convertRequestUrl($item->request);
$this->convertResponseUrls($item->response);
}
}
/**
* Converts auth object from v2.0 to v2.1
*
* @param object $request
* @return void
*/
protected function convertAuth(object $request): void
{
if (empty($request->auth)) {
return;
}
$type = $request->auth->type;
if ($type !== 'noauth' && isset($request->auth->$type)) {
$auth = [];
foreach ($request->auth->$type as $key => $value) {
$auth[] = (object)[
'key' => $key,
'value' => $value,
'type' => 'string',
];
}
$request->auth->$type = $auth;
}
}
/**
* Converts requests URLs from string v2.0 to object v2.1
*
* @param object $request
* @return void
*/
protected function convertRequestUrl(object $request): void
{
if (is_string($request->url) && mb_strlen($request->url) > 0) {
$data = array_values(array_filter(explode('/', $request->url))); //TODO URL parsing
if (count($data) === 1) {
$url = [
'raw' => $request->url,
'host' => [$data[0] ?? $request->url],
];
} else {
$url = [
'raw' => $request->url,
'protocol' => str_replace(':', '', $data[0]),
'host' => [$data[1] ?? $request->url],
'path' => array_slice($data, 2),
];
}
$request->url = (object)$url;
}
}
/**
* Converts URLs response examples from string v2.0 to object v2.1
*
* @param array $responses
* @return void
*/
protected function convertResponseUrls(array $responses): void
{
foreach ($responses as $response) {
if (is_string($response->originalRequest->url)) {
$data = array_values(array_filter(explode('/', $response->originalRequest->url))); //TODO URL parsing
if (count($data) === 1) {
$url = [
'raw' => $response->originalRequest->url,
'host' => [$data[0] ?? $response->originalRequest->url],
];
} else {
$url = [
'raw' => $response->originalRequest->url,
'protocol' => str_replace(':', '', $data[0]),
'host' => [$data[1] ?? $response->originalRequest->url],
'path' => array_slice($data, 2),
];
}
$response->originalRequest->url = (object)$url;
}
}
}
}

View File

@ -12,12 +12,14 @@ class Environment implements \ArrayAccess
protected array $vars = [];
/**
* @param object $env
* @param object|null $env
*/
public function __construct(protected object $env)
public function __construct(protected ?object $env)
{
foreach ($env->values as $var) {
$this->vars[static::formatKey($var->key)] = $var->value;
if (!empty($env->values)) {
foreach ($env->values as $var) {
$this->vars[static::formatKey($var->key)] = $var->value;
}
}
}

View File

@ -54,7 +54,7 @@ class Processor
protected array $converters = [];
/**
* @var object[] Collections that will be converted into choosen formats
* @var Collection[] Collections that will be converted into choosen formats
*/
protected array $collections = [];
@ -93,6 +93,7 @@ class Processor
* Parses an array of arguments came from cli
*
* @return void
* @throws JsonException
*/
protected function parseArgs(): void
{
@ -160,6 +161,10 @@ class Processor
$this->formats[ConvertFormat::Postman20->name] = ConvertFormat::Postman20;
break;
case '--v2.1':
$this->formats[ConvertFormat::Postman21->name] = ConvertFormat::Postman21;
break;
case '--var':
[$var, $value] = explode('=', trim($this->argv[$idx + 1]));
$this->vars[$var] = $value;
@ -297,8 +302,13 @@ class Processor
protected function printStats(int $success, int $count): void
{
$time = (hrtime(true) - $this->initTime) / 1_000_000;
$timeFmt = 'ms';
if ($time > 1000) {
$time /= 1000;
$timeFmt = 'sec';
}
$ram = (memory_get_peak_usage(true) - $this->initRam) / 1024 / 1024;
printf('Converted %d of %d in %.3f ms using up to %.3f MiB RAM%s', $success, $count, $time, $ram, PHP_EOL);
printf("Converted %d/%d in %.2f $timeFmt using up to %.2f MiB RAM%s", $success, $count, $time, $ram, PHP_EOL);
}
/**