Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 593546e3ff | |||
|
771fe4931a
|
|||
|
c6bdcfe7cc
|
|||
|
60cad4b501
|
|||
|
01d29ee023
|
|||
|
3c1871ce1f
|
|||
| c6963e0574 | |||
|
5c85f23514
|
|||
|
35e1984326
|
|||
| 83794a7464 | |||
|
1dc5f7deaf
|
|||
|
0b4317f56a
|
|||
|
8ab615c062
|
|||
|
da763a5a2f
|
|||
| af9406be47 | |||
|
1345b7eddb
|
|||
| 3734327357 | |||
|
af9c360684
|
|||
|
44f437eaf3
|
|||
|
1ebdffe2a6
|
|||
| d854732143 | |||
|
9b021296eb
|
|||
|
d581afa793
|
|||
| 95ca655eb0 | |||
|
25887a47d3
|
|||
|
1f7816c917
|
|||
|
fb7b4baa32
|
|||
|
2c4eedbf8b
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,5 @@
|
||||
/.idea
|
||||
/.vscode
|
||||
/vendor
|
||||
.phpunit.result.cache
|
||||
.phpunit.cache
|
||||
|
||||
104
README.md
104
README.md
@@ -26,16 +26,17 @@ These formats are supported for now: `http`, `curl`, `wget`.
|
||||
|
||||
- support as many as possible/necessary of authentication kinds (_currently only `Bearer` supported_);
|
||||
- support as many as possible/necessary of body formats (_currently only `json` and `formdata`_);
|
||||
- documentation generation support (markdown) with responce examples (if present);
|
||||
- documentation generation support (markdown) with response examples (if present) (#6);
|
||||
- maybe some another convert formats (like httpie or something...);
|
||||
- better logging;
|
||||
- tests, phpcs, psalm, etc.;
|
||||
- 90%+ test coverage, phpcs, psalm, etc.;
|
||||
- web version.
|
||||
|
||||
## Installation
|
||||
## Install and upgrade
|
||||
|
||||
```
|
||||
composer global r axenov/pm-convert
|
||||
composer global r axenov/pm-convert # install
|
||||
composer global u axenov/pm-convert # upgrade
|
||||
```
|
||||
|
||||
Make sure your `~/.config/composer/vendor/bin` is in `$PATH` env:
|
||||
@@ -58,45 +59,88 @@ Usage:
|
||||
./vendor/bin/pm-convert -f|-d PATH -o OUTPUT_PATH [ARGUMENTS] [FORMATS]
|
||||
|
||||
Possible ARGUMENTS:
|
||||
-f, --file - a PATH to single collection located in PATH to convert from
|
||||
-d, --dir - a directory with collections located in COLLECTION_FILEPATH to convert from
|
||||
-o, --output - a directory OUTPUT_PATH to put results in
|
||||
-e, --env - use environment file with variable values to replace in request
|
||||
-p, --preserve - do not delete OUTPUT_PATH (if exists)
|
||||
-h, --help - show this help message and exit
|
||||
-v, --version - show version info and exit
|
||||
-f, --file - a PATH to a single collection file to convert from
|
||||
-d, --dir - a PATH to a directory with collections to convert from
|
||||
-o, --output - a directory OUTPUT_PATH to put results in
|
||||
-e, --env - use environment file with variables to replace in requests
|
||||
--var "NAME=VALUE" - force replace specified env variable called NAME with custom VALUE
|
||||
-p, --preserve - do not delete OUTPUT_PATH (if exists)
|
||||
-h, --help - show this help message and exit
|
||||
-v, --version - show version info and exit
|
||||
|
||||
If no ARGUMENTS passed then --help implied.
|
||||
If both -f and -d are specified then only unique set of files will be converted.
|
||||
If both -f and -d are specified then only unique set of files from both arguments will be converted.
|
||||
-f or -d are required to be specified at least once, but each may be specified multiple times.
|
||||
PATH must be a valid path to readable json-file or directory.
|
||||
OUTPUT_PATH must be a valid path to writeable directory.
|
||||
If -o is specified several times then only last one will be used.
|
||||
If -e is specified several times then only last one will be used.
|
||||
If -e is not specified then only collection vars will be replaced (if any).
|
||||
If -o or -e was specified several times then only last one will be used.
|
||||
|
||||
Possible FORMATS:
|
||||
--http - generate raw *.http files (default)
|
||||
--curl - generate shell scripts with curl command
|
||||
--wget - generate shell scripts with wget command
|
||||
--http - generate raw *.http files (default)
|
||||
--curl - generate shell scripts with curl command
|
||||
--wget - generate shell scripts with wget command
|
||||
--v2.0 - convert from Postman Collection Schema v2.1 into v2.0
|
||||
--v2.1 - convert from Postman Collection Schema v2.0 into v2.1
|
||||
-a, --all - convert to all of formats listed above
|
||||
|
||||
If no FORMATS specified then --http implied.
|
||||
Any of FORMATS can be specified at the same time.
|
||||
Any of FORMATS can be specified at the same time or replaced by --all.
|
||||
|
||||
Example:
|
||||
./pm-convert \
|
||||
-f ~/dir1/first.postman_collection.json \
|
||||
--directory ~/team \
|
||||
--file ~/dir2/second.postman_collection.json \
|
||||
--env ~/localhost.postman_environment.json \
|
||||
-d ~/personal \
|
||||
-o ~/postman_export
|
||||
./pm-convert \
|
||||
-f ~/dir1/first.postman_collection.json \
|
||||
--directory ~/team \
|
||||
--file ~/dir2/second.postman_collection.json \
|
||||
--env ~/localhost.postman_environment.json \
|
||||
-d ~/personal \
|
||||
--var "myvar=some value" \
|
||||
-o ~/postman_export \
|
||||
--all
|
||||
```
|
||||
|
||||
### Notices
|
||||
|
||||
1. Result of `pm-convert` execution is bunch of generated files.
|
||||
Most likely they will contain errors such as not interpolated `{{variables}}` values (due to missed ones in collection),
|
||||
wrong command format or `GET`s with bodies.
|
||||
You must review any generated file before using.
|
||||
2. Make sure every (I mean _every_) collection (not collection file), its folders and/or requests has unique names.
|
||||
If not, you can rename them in Postman or convert collections with similar names into different directories.
|
||||
Otherwise any generated file may be accidently overwritten by another one.
|
||||
|
||||
## Notes about variable interpolation
|
||||
|
||||
1. You can use -e to tell where to find variables to replace in requests.
|
||||
2. You can use one or several --var to replace specific env variables to your own value.
|
||||
3. Correct syntax is `--var "NAME=VALUE"`. `NAME` may be in curly braces like `{{NAME}}`.
|
||||
4. Since -e is optional, a bunch of `--var` will emulate an environment. Also it does not matter if there is `--var` in environment file you provided or not.
|
||||
5. Even if you (not) provided -e and/or `--var`, any of variable may still be overridden from collection (if any), so last ones has top priority.
|
||||
|
||||
### Notes about conversion between Postman Schemas
|
||||
|
||||
You can use `--v2.1` to convert v2.1 into v2.1 (and this is not a typo).
|
||||
Same applies to `--v2.0`.
|
||||
|
||||
There is a case when a collection has been exported via Postman API.
|
||||
In such case collection itself places in single root object called `collection` like this:
|
||||
|
||||
```
|
||||
### Notice
|
||||
{
|
||||
"collection": {
|
||||
// your actual collection here
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Make sure every (I mean _every_) collection (not collection file), its folders and/or requests has unique names.
|
||||
If not, you can rename them in Postman or convert collections with similar names into different directories.
|
||||
Otherwise converted files may be overwritten by each other.
|
||||
So, pm-convert will just raise actual data up on top level and write into disk.
|
||||
|
||||
## How to implement a new format
|
||||
|
||||
1. Create new namespace in `./src/Converters` and name it according to format of your choice.
|
||||
2. Create two classes for converter and request object which extends `Converters\Abstract\Abstract{Converter, Request}` respectively.
|
||||
3. Change constants values in your new request class according to format you want to implement.
|
||||
4. Add your converter class name in `Converters\ConvertFormat`.
|
||||
5. Write your own logic in converter, write new methods and override abstract ones.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "axenov/pm-convert",
|
||||
"type": "library",
|
||||
"description": "Postman collection coverter",
|
||||
"description": "Postman collection converter",
|
||||
"license": "MIT",
|
||||
"homepage": "https://axenov.dev/",
|
||||
"authors": [
|
||||
@@ -13,11 +13,10 @@
|
||||
"keywords": ["postman", "collection", "converter", "http", "wget", "curl", "api", "convert"],
|
||||
"require": {
|
||||
"php": "^8.1",
|
||||
"ext-json": "*"
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"bin": [
|
||||
"pm-convert"
|
||||
],
|
||||
"bin": ["pm-convert"],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PmConverter\\": "src\\"
|
||||
@@ -30,5 +29,8 @@
|
||||
"optimize-autoloader": true,
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^10.3"
|
||||
}
|
||||
}
|
||||
|
||||
1614
composer.lock
generated
1614
composer.lock
generated
File diff suppressed because it is too large
Load Diff
26
phpunit.xml
Normal file
26
phpunit.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.3/phpunit.xsd"
|
||||
bootstrap="vendor/autoload.php"
|
||||
cacheDirectory=".phpunit.cache"
|
||||
executionOrder="depends,defects"
|
||||
requireCoverageMetadata="true"
|
||||
beStrictAboutCoverageMetadata="true"
|
||||
beStrictAboutOutputDuringTests="true"
|
||||
failOnRisky="true"
|
||||
failOnWarning="true">
|
||||
<testsuites>
|
||||
<testsuite name="Main">
|
||||
<!-- <directory>tests</directory>-->
|
||||
<file>tests/AbstractRequestTest.php</file>
|
||||
<file>tests/HttpRequestTest.php</file>
|
||||
<file>tests/WgetRequestTest.php</file>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<source restrictDeprecations="true" restrictNotices="true" restrictWarnings="true">
|
||||
<include>
|
||||
<directory>src</directory>
|
||||
</include>
|
||||
</source>
|
||||
</phpunit>
|
||||
99
src/Collection.php
Normal file
99
src/Collection.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace PmConverter;
|
||||
|
||||
use JsonException;
|
||||
use Stringable;
|
||||
|
||||
/**
|
||||
* Class that describes a request collection
|
||||
*
|
||||
* @property array|object $item
|
||||
* @property object $info
|
||||
* @property object|null $variable
|
||||
*/
|
||||
class Collection implements Stringable
|
||||
{
|
||||
/**
|
||||
* Closed constructor so that we could use factory methods
|
||||
*
|
||||
* @param object $json
|
||||
*/
|
||||
private function __construct(protected object $json)
|
||||
{
|
||||
// specific case when collection has been exported via postman api
|
||||
if (isset($json->collection)) {
|
||||
$json = $json->collection;
|
||||
}
|
||||
$this->json = $json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory that creates new Collection from content read from file path
|
||||
*
|
||||
* @param string $path
|
||||
* @return static
|
||||
* @throws JsonException
|
||||
*/
|
||||
public static function fromFile(string $path): static
|
||||
{
|
||||
$content = file_get_contents(FileSystem::normalizePath($path));
|
||||
$json = json_decode($content, flags: JSON_THROW_ON_ERROR);
|
||||
return new static($json);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
return json_encode($this->json, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns reference to the parsed json structure
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function &raw(): object
|
||||
{
|
||||
return $this->json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns reference to any part of the parsed json structure
|
||||
*
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function &__get(string $name): mixed
|
||||
{
|
||||
return $this->json->$name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns collection name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function name(): string
|
||||
{
|
||||
return $this->json->info->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the collection version
|
||||
*
|
||||
* @return CollectionVersion
|
||||
*/
|
||||
public function version(): CollectionVersion
|
||||
{
|
||||
return match (true) {
|
||||
str_contains($this->json->info->schema, '/v2.0.') => CollectionVersion::Version20,
|
||||
str_contains($this->json->info->schema, '/v2.1.') => CollectionVersion::Version21,
|
||||
default => CollectionVersion::Unknown
|
||||
};
|
||||
}
|
||||
}
|
||||
12
src/CollectionVersion.php
Normal file
12
src/CollectionVersion.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter;
|
||||
|
||||
enum CollectionVersion: string
|
||||
{
|
||||
case Version20 = 'v2.0';
|
||||
case Version21 = 'v2.1';
|
||||
case Unknown = 'unknown';
|
||||
}
|
||||
@@ -2,13 +2,18 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Exporters\Abstract;
|
||||
namespace PmConverter\Converters\Abstract;
|
||||
|
||||
use Exception;
|
||||
use PmConverter\Environment;
|
||||
use PmConverter\Exporters\{
|
||||
use PmConverter\Collection;
|
||||
use PmConverter\Converters\{
|
||||
ConverterContract,
|
||||
RequestContract};
|
||||
use PmConverter\Environment;
|
||||
use PmConverter\Exceptions\{
|
||||
CannotCreateDirectoryException,
|
||||
DirectoryIsNotWriteableException,
|
||||
InvalidHttpVersionException};
|
||||
use PmConverter\FileSystem;
|
||||
|
||||
/**
|
||||
@@ -17,9 +22,9 @@ use PmConverter\FileSystem;
|
||||
abstract class AbstractConverter implements ConverterContract
|
||||
{
|
||||
/**
|
||||
* @var object|null
|
||||
* @var Collection|null
|
||||
*/
|
||||
protected ?object $collection = null;
|
||||
protected ?Collection $collection = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
@@ -27,14 +32,9 @@ abstract class AbstractConverter implements ConverterContract
|
||||
protected string $outputPath;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* @var Environment|null
|
||||
*/
|
||||
protected array $vars = [];
|
||||
|
||||
/**
|
||||
* @var Environment
|
||||
*/
|
||||
protected Environment $env;
|
||||
protected ?Environment $env = null;
|
||||
|
||||
/**
|
||||
* Sets an environment with vars
|
||||
@@ -49,14 +49,32 @@ abstract class AbstractConverter implements ConverterContract
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts collection requests
|
||||
* Creates a new directory to save a converted collection into
|
||||
*
|
||||
* @throws Exception
|
||||
* @param string $outputPath
|
||||
* @return void
|
||||
* @throws CannotCreateDirectoryException
|
||||
* @throws DirectoryIsNotWriteableException
|
||||
*/
|
||||
public function convert(object $collection, string $outputPath): void
|
||||
protected function prepareOutputDir(string $outputPath): void
|
||||
{
|
||||
$outputPath = sprintf('%s%s%s', $outputPath, DIRECTORY_SEPARATOR, static::OUTPUT_DIR);
|
||||
$this->outputPath = FileSystem::makeDir($outputPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts collection requests
|
||||
*
|
||||
* @param Collection $collection
|
||||
* @param string $outputPath
|
||||
* @return void
|
||||
* @throws CannotCreateDirectoryException
|
||||
* @throws DirectoryIsNotWriteableException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function convert(Collection $collection, string $outputPath): void
|
||||
{
|
||||
$this->prepareOutputDir($outputPath);
|
||||
$this->collection = $collection;
|
||||
$this->setVariables();
|
||||
foreach ($collection->item as $item) {
|
||||
@@ -71,9 +89,10 @@ abstract class AbstractConverter implements ConverterContract
|
||||
*/
|
||||
protected function setVariables(): static
|
||||
{
|
||||
if ($this->collection->variable) {
|
||||
empty($this->env) && $this->env = new Environment($this->collection?->variable);
|
||||
if (!empty($this->collection?->variable)) {
|
||||
foreach ($this->collection->variable as $var) {
|
||||
$this->vars["{{{$var->key}}}"] = $var->value;
|
||||
$this->env[$var->key] = $var->value;
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
@@ -97,7 +116,9 @@ abstract class AbstractConverter implements ConverterContract
|
||||
*/
|
||||
protected function isItemFolder(object $item): bool
|
||||
{
|
||||
return !empty($item->item) && empty($item->request);
|
||||
return !empty($item->item)
|
||||
&& is_array($item->item)
|
||||
&& empty($item->request);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -129,23 +150,25 @@ abstract class AbstractConverter implements ConverterContract
|
||||
*
|
||||
* @param object $item
|
||||
* @return RequestContract
|
||||
* @throws InvalidHttpVersionException
|
||||
*/
|
||||
protected function initRequest(object $item): RequestContract
|
||||
{
|
||||
$request_class = static::REQUEST_CLASS;
|
||||
|
||||
/** @var RequestContract $result */
|
||||
$result = new $request_class($this->vars);
|
||||
$result->setName($item->name);
|
||||
$result->setDescription($item->request?->description ?? null);
|
||||
$result->setVerb($item->request->method);
|
||||
$result->setUrl($item->request->url->raw);
|
||||
$result->setHeaders($item->request->header);
|
||||
$result->setAuth($item->request?->auth ?? $this->collection?->auth ?? null);
|
||||
/** @var RequestContract $request */
|
||||
$request = new $request_class();
|
||||
$request->setName($item->name);
|
||||
$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->setHeaders($item->request->header);
|
||||
$request->setAuth($item->request?->auth ?? $this->collection?->auth ?? null);
|
||||
if ($item->request->method !== 'GET' && !empty($item->request->body)) {
|
||||
$result->setBody($item->request->body);
|
||||
$request->setBody($item->request->body);
|
||||
}
|
||||
return $result;
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -173,21 +196,18 @@ abstract class AbstractConverter implements ConverterContract
|
||||
*/
|
||||
protected function interpolate(string $content): string
|
||||
{
|
||||
if (empty($this->vars) && $this->env->hasVars()) {
|
||||
if (!$this->env?->hasVars()) {
|
||||
return $content;
|
||||
}
|
||||
$matches = [];
|
||||
if (preg_match_all('/\{\{[a-zA-Z][a-zA-Z0-9]+}}/', $content, $matches, PREG_PATTERN_ORDER) > 0) {
|
||||
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->vars[$var] ?? $this->env[$var] ?? $var, $content);
|
||||
$content = str_replace($var, $this->env[$var] ?: $var, $content);
|
||||
unset($matches[0][$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (!empty($matches[0])) {
|
||||
// fwrite(STDERR, sprintf(' No values found: %s%s', implode(', ', $matches[0]), PHP_EOL));
|
||||
// }
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
296
src/Converters/Abstract/AbstractRequest.php
Normal file
296
src/Converters/Abstract/AbstractRequest.php
Normal file
@@ -0,0 +1,296 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Converters\Abstract;
|
||||
|
||||
use PmConverter\Converters\RequestContract;
|
||||
use PmConverter\Exceptions\{
|
||||
EmptyHttpVerbException,
|
||||
InvalidHttpVersionException};
|
||||
use PmConverter\HttpVersion;
|
||||
use Stringable;
|
||||
|
||||
/**
|
||||
* Class to determine file content with any request format
|
||||
*/
|
||||
abstract class AbstractRequest implements Stringable, RequestContract
|
||||
{
|
||||
/**
|
||||
* @var string HTTP verb (GET, POST, etc.)
|
||||
*/
|
||||
protected string $verb;
|
||||
|
||||
/**
|
||||
* @var string URL where to send a request
|
||||
*/
|
||||
protected string $url;
|
||||
|
||||
/**
|
||||
* @var float HTTP protocol version
|
||||
*/
|
||||
protected float $httpVersion = 1.1;
|
||||
|
||||
/**
|
||||
* @var string Request name
|
||||
*/
|
||||
protected string $name;
|
||||
|
||||
/**
|
||||
* @var string|null Request description
|
||||
*/
|
||||
protected ?string $description = null;
|
||||
|
||||
/**
|
||||
* @var array Request headers
|
||||
*/
|
||||
protected array $headers = [];
|
||||
|
||||
/**
|
||||
* @var mixed Request body
|
||||
*/
|
||||
protected mixed $body = null;
|
||||
|
||||
/**
|
||||
* @var string Request body type
|
||||
*/
|
||||
protected string $bodymode = 'raw';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setHttpVersion(float $version): static
|
||||
{
|
||||
if (!in_array($version, HttpVersion::values())) {
|
||||
throw new InvalidHttpVersionException(
|
||||
'Only these HTTP versions are supported: ' . implode(', ', HttpVersion::values())
|
||||
);
|
||||
}
|
||||
$this->httpVersion = $version;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getHttpVersion(): float
|
||||
{
|
||||
return $this->httpVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setName(string $name): static
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return str_replace(DIRECTORY_SEPARATOR, '_', $this->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setDescription(?string $description): static
|
||||
{
|
||||
$this->description = $description;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getDescription(): ?string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setVerb(string $verb): static
|
||||
{
|
||||
$this->verb = $verb;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getVerb(): string
|
||||
{
|
||||
empty($this->verb) && throw new EmptyHttpVerbException('Request HTTP verb must be defined before conversion');
|
||||
return $this->verb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setUrl(string $url): static
|
||||
{
|
||||
$this->url = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getUrl(): string
|
||||
{
|
||||
return $this->url ?: '<empty url>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setHeaders(?array $headers): static
|
||||
{
|
||||
foreach ($headers as $header) {
|
||||
$this->setHeader($header->key, $header->value, $header?->disabled ?? false);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setHeader(string $name, mixed $value, bool $disabled = false): static
|
||||
{
|
||||
$this->headers[$name] = [
|
||||
'value' => $value,
|
||||
'disabled' => $disabled,
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getHeaders(): array
|
||||
{
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setAuth(?object $auth): static
|
||||
{
|
||||
if (!empty($auth)) {
|
||||
switch ($auth->type) {
|
||||
case 'bearer':
|
||||
$this->setHeader('Authorization', 'Bearer ' . $auth->{$auth->type}[0]->value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setBodymode(string $bodymode): static
|
||||
{
|
||||
$this->bodymode = $bodymode;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getBodymode(): string
|
||||
{
|
||||
return $this->bodymode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setBody(object $body): static
|
||||
{
|
||||
$this->setBodymode($body->mode);
|
||||
if ($body->mode === 'formdata') {
|
||||
$this->setHeader('Content-Type', 'multipart/form-data')->setFormdataBody($body);
|
||||
} elseif ($body->mode === 'raw') {
|
||||
$this->setBodyAsIs($body);
|
||||
if (!empty($body->options) && $body->options->{$this->bodymode}->language === 'json') {
|
||||
$this->setHeader('Content-Type', 'application/json');
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets body content from multipart/formdata
|
||||
*
|
||||
* @param object $body
|
||||
* @return $this
|
||||
*/
|
||||
protected function setFormdataBody(object $body): static
|
||||
{
|
||||
foreach ($body->formdata as $field) {
|
||||
$this->body[$field->key] = [
|
||||
'value' => $field->type === 'file' ? $field->src : $field->value,
|
||||
'type' => $field->type,
|
||||
];
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets body content from application/json
|
||||
*
|
||||
* @param object $body
|
||||
* @return $this
|
||||
*/
|
||||
protected function setBodyAsIs(object $body): static
|
||||
{
|
||||
$this->body = $body->{$this->getBodymode()};
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getBody(): mixed
|
||||
{
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array of description lines
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function prepareDescription(): array;
|
||||
|
||||
/**
|
||||
* Returns array of headers
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function prepareHeaders(): array;
|
||||
|
||||
/**
|
||||
* Returns array of request body lines
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function prepareBody(): array;
|
||||
|
||||
/**
|
||||
* Converts request object to string to be written in result file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function __toString(): string;
|
||||
}
|
||||
22
src/Converters/ConvertFormat.php
Normal file
22
src/Converters/ConvertFormat.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Converters;
|
||||
|
||||
|
||||
use PmConverter\Converters\{
|
||||
Curl\CurlConverter,
|
||||
Http\HttpConverter,
|
||||
Postman20\Postman20Converter,
|
||||
Postman21\Postman21Converter,
|
||||
Wget\WgetConverter};
|
||||
|
||||
enum ConvertFormat: string
|
||||
{
|
||||
case Http = HttpConverter::class;
|
||||
case Curl = CurlConverter::class;
|
||||
case Wget = WgetConverter::class;
|
||||
case Postman20 = Postman20Converter::class;
|
||||
case Postman21 = Postman21Converter::class;
|
||||
}
|
||||
13
src/Converters/ConverterContract.php
Normal file
13
src/Converters/ConverterContract.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Converters;
|
||||
|
||||
use PmConverter\Collection;
|
||||
|
||||
interface ConverterContract
|
||||
{
|
||||
public function convert(Collection $collection, string $outputPath): void;
|
||||
public function getOutputPath(): string;
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Exporters\Curl;
|
||||
namespace PmConverter\Converters\Curl;
|
||||
|
||||
use PmConverter\Exporters\{
|
||||
use PmConverter\Converters\{
|
||||
Abstract\AbstractConverter,
|
||||
ConverterContract};
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Exporters\Curl;
|
||||
namespace PmConverter\Converters\Curl;
|
||||
|
||||
use PmConverter\Exporters\Abstract\AbstractRequest;
|
||||
use PmConverter\Converters\Abstract\AbstractRequest;
|
||||
|
||||
/**
|
||||
* Class to determine file content with curl request format
|
||||
@@ -31,7 +31,7 @@ class CurlRequest extends AbstractRequest
|
||||
if ($header['disabled']) {
|
||||
continue;
|
||||
}
|
||||
$output[] = sprintf("\t--header '%s=%s' \ ", $header_key, $header['value']);
|
||||
$output[] = sprintf("\t--header '%s: %s' \ ", $header_key, $header['value']);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
@@ -44,12 +44,12 @@ class CurlRequest extends AbstractRequest
|
||||
$output = [];
|
||||
switch ($this->bodymode) {
|
||||
case 'formdata':
|
||||
foreach ($this->body as $data) {
|
||||
foreach ($this->body as $key => $data) {
|
||||
$output[] = sprintf(
|
||||
"%s\t--form '%s=%s' \ ",
|
||||
isset($data->disabled) ? '# ' : '',
|
||||
$data->key,
|
||||
$data->type === 'file' ? "@$data->src" : $data->value
|
||||
isset($data['disabled']) ? '# ' : '',
|
||||
$key,
|
||||
$data['type'] === 'file' ? "@" . $data['value'] : $data['value']
|
||||
);
|
||||
}
|
||||
break;
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Exporters\Http;
|
||||
namespace PmConverter\Converters\Http;
|
||||
|
||||
use PmConverter\Exporters\{
|
||||
use PmConverter\Converters\{
|
||||
Abstract\AbstractConverter,
|
||||
ConverterContract};
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Exporters\Http;
|
||||
namespace PmConverter\Converters\Http;
|
||||
|
||||
use PmConverter\Exporters\Abstract\AbstractRequest;
|
||||
use PmConverter\Converters\Abstract\AbstractRequest;
|
||||
use PmConverter\Exceptions\{
|
||||
EmptyHttpVerbException};
|
||||
|
||||
/**
|
||||
* Class to determine file content with http request format
|
||||
@@ -23,12 +25,13 @@ class HttpRequest extends AbstractRequest
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws EmptyHttpVerbException
|
||||
*/
|
||||
protected function prepareHeaders(): array
|
||||
{
|
||||
$output[] = "$this->verb $this->url $this->http";
|
||||
foreach ($this->headers as $header_key => $header) {
|
||||
$output[] = sprintf('%s%s: %s', $header['disabled'] ? '# ' : '', $header_key, $header['value']);
|
||||
$output[] = sprintf('%s %s HTTP/%s', $this->getVerb(), $this->getUrl(), $this->getHttpVersion());
|
||||
foreach ($this->headers as $name => $data) {
|
||||
$output[] = sprintf('%s%s: %s', $data['disabled'] ? '# ' : '', $name, $data['value']);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
@@ -38,15 +41,15 @@ class HttpRequest extends AbstractRequest
|
||||
*/
|
||||
protected function prepareBody(): array
|
||||
{
|
||||
switch ($this->bodymode) {
|
||||
switch ($this->getBodymode()) {
|
||||
case 'formdata':
|
||||
$output = [''];
|
||||
foreach ($this->body as $data) {
|
||||
foreach ($this->body as $key => $data) {
|
||||
$output[] = sprintf(
|
||||
'%s%s=%s',
|
||||
empty($data->disabled) ? '' : '# ',
|
||||
$data->key,
|
||||
$data->type === 'file' ? $data->src : $data->value
|
||||
empty($data['disabled']) ? '' : '# ',
|
||||
$key,
|
||||
$data['type'] === 'file' ? '@' . $data['value'] : $data['value']
|
||||
);
|
||||
}
|
||||
return $output;
|
||||
@@ -57,6 +60,7 @@ class HttpRequest extends AbstractRequest
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws EmptyHttpVerbException
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
137
src/Converters/Postman20/Postman20Converter.php
Normal file
137
src/Converters/Postman20/Postman20Converter.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Converters\Postman20;
|
||||
|
||||
use PmConverter\Collection;
|
||||
use PmConverter\CollectionVersion;
|
||||
use PmConverter\Converters\{
|
||||
Abstract\AbstractConverter,
|
||||
ConverterContract};
|
||||
use PmConverter\Exceptions\CannotCreateDirectoryException;
|
||||
use PmConverter\Exceptions\DirectoryIsNotWriteableException;
|
||||
use PmConverter\FileSystem;
|
||||
|
||||
/**
|
||||
* Converts Postman Collection v2.1 to v2.0
|
||||
*/
|
||||
class Postman20Converter extends AbstractConverter implements ConverterContract
|
||||
{
|
||||
protected const FILE_EXT = 'v20.postman_collection.json';
|
||||
|
||||
protected const OUTPUT_DIR = 'pm-v2.0';
|
||||
|
||||
/**
|
||||
* 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;
|
||||
// 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) {
|
||||
$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->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.1 to v2.0
|
||||
*
|
||||
* @param object $request
|
||||
* @return void
|
||||
*/
|
||||
protected function convertAuth(object $request): void
|
||||
{
|
||||
if (empty($request->auth)) {
|
||||
return;
|
||||
}
|
||||
$type = $request->auth->type;
|
||||
if ($type !== 'noauth' && is_array($request->auth->$type)) {
|
||||
$auth = [];
|
||||
foreach ($request->auth->$type as $param) {
|
||||
$auth[$param->key] = $param->value;
|
||||
}
|
||||
$request->auth->$type = (object)$auth;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts requests URLs from object v2.1 to string v2.0
|
||||
*
|
||||
* @param object $request
|
||||
* @return void
|
||||
*/
|
||||
protected function convertRequestUrl(object $request): void
|
||||
{
|
||||
if (is_object($request->url)) {
|
||||
$request->url = $request->url->raw;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts URLs response examples from object v2.1 to string v2.0
|
||||
*
|
||||
* @param array $responses
|
||||
* @return void
|
||||
*/
|
||||
protected function convertResponseUrls(array $responses): void
|
||||
{
|
||||
foreach ($responses as $response) {
|
||||
if (is_object($response->originalRequest->url)) {
|
||||
$response->originalRequest->url = $response->originalRequest->url->raw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
169
src/Converters/Postman21/Postman21Converter.php
Normal file
169
src/Converters/Postman21/Postman21Converter.php
Normal file
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Converters\Postman21;
|
||||
|
||||
use PmConverter\Collection;
|
||||
use PmConverter\CollectionVersion;
|
||||
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;
|
||||
// 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) {
|
||||
$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->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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
153
src/Converters/RequestContract.php
Normal file
153
src/Converters/RequestContract.php
Normal file
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Converters;
|
||||
|
||||
use PmConverter\Converters\Http\HttpRequest;
|
||||
use PmConverter\Exceptions\{
|
||||
EmptyHttpVerbException,
|
||||
InvalidHttpVersionException};
|
||||
|
||||
interface RequestContract
|
||||
{
|
||||
/**
|
||||
* Sets HTTP protocol version
|
||||
*
|
||||
* @param float $version
|
||||
* @return $this
|
||||
* @throws InvalidHttpVersionException
|
||||
*/
|
||||
public function setHttpVersion(float $version): static;
|
||||
|
||||
/**
|
||||
* Returns HTTP protocol version
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getHttpVersion(): float;
|
||||
|
||||
/**
|
||||
* Sets name from collection item to request object
|
||||
*
|
||||
* @param string $name
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public function setName(string $name): static;
|
||||
|
||||
/**
|
||||
* Returns name of request
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string;
|
||||
|
||||
/**
|
||||
* Sets description from collection item to request object
|
||||
*
|
||||
* @param string|null $description
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public function setDescription(?string $description): static;
|
||||
|
||||
/**
|
||||
* Returns description request
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getDescription(): ?string;
|
||||
|
||||
/**
|
||||
* Sets HTTP verb from collection item to request object
|
||||
*
|
||||
* @param string $verb
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public function setVerb(string $verb): static;
|
||||
|
||||
/**
|
||||
* Returns HTTP verb of request
|
||||
*
|
||||
* @return string
|
||||
* @throws EmptyHttpVerbException
|
||||
*/
|
||||
public function getVerb(): string;
|
||||
|
||||
/**
|
||||
* Sets URL from collection item to request object
|
||||
*
|
||||
* @param string $url
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public function setUrl(string $url): static;
|
||||
|
||||
/**
|
||||
* Returns URL of request
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl(): string;
|
||||
|
||||
/**
|
||||
* Sets headers from collection item to request object
|
||||
*
|
||||
* @param object[]|null $headers
|
||||
* @return $this
|
||||
*/
|
||||
public function setHeaders(?array $headers): static;
|
||||
|
||||
/**
|
||||
* Sets one header to request object
|
||||
*
|
||||
* @param string $name Header's name
|
||||
* @param mixed $value Header's value
|
||||
* @param bool $disabled Pass true to skip (or comment out) this header
|
||||
* @return $this
|
||||
*/
|
||||
public function setHeader(string $name, mixed $value, bool $disabled = false): static;
|
||||
|
||||
/**
|
||||
* Returns array of prepared headers
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders(): array;
|
||||
|
||||
/**
|
||||
* Sets authorization headers
|
||||
*
|
||||
* @param object|null $auth
|
||||
* @return $this
|
||||
*/
|
||||
public function setAuth(object $auth): static;
|
||||
|
||||
/**
|
||||
* Sets body mode from collection item to request object
|
||||
*
|
||||
* @param string $bodymode
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public function setBodymode(string $bodymode): static;
|
||||
|
||||
/**
|
||||
* Returns body mode of request
|
||||
*
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public function getBodymode(): string;
|
||||
|
||||
/**
|
||||
* Sets body from collection item to request object
|
||||
*
|
||||
* @param object $body
|
||||
* @return $this
|
||||
*/
|
||||
public function setBody(object $body): static;
|
||||
|
||||
/**
|
||||
* Returns body content
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBody(): mixed;
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Exporters\Wget;
|
||||
namespace PmConverter\Converters\Wget;
|
||||
|
||||
use PmConverter\Exporters\{
|
||||
use PmConverter\Converters\{
|
||||
Abstract\AbstractConverter,
|
||||
ConverterContract};
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Exporters\Wget;
|
||||
namespace PmConverter\Converters\Wget;
|
||||
|
||||
use PmConverter\Exporters\Abstract\AbstractRequest;
|
||||
use PmConverter\Converters\Abstract\AbstractRequest;
|
||||
use PmConverter\Exceptions\EmptyHttpVerbException;
|
||||
|
||||
/**
|
||||
* Class to determine file content with wget request format
|
||||
@@ -31,7 +32,7 @@ class WgetRequest extends AbstractRequest
|
||||
if ($header['disabled']) {
|
||||
continue;
|
||||
}
|
||||
$output[] = sprintf("\t--header '%s=%s' \ ", $header_key, $header['value']);
|
||||
$output[] = sprintf("\t--header '%s: %s' \ ", $header_key, $header['value']);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
@@ -43,22 +44,22 @@ class WgetRequest extends AbstractRequest
|
||||
{
|
||||
switch ($this->bodymode) {
|
||||
case 'formdata':
|
||||
$params = [];
|
||||
foreach ($this->body as $data) {
|
||||
if ($data->type === 'file') {
|
||||
$output = [];
|
||||
foreach ($this->body as $key => $data) {
|
||||
if ($data['type'] === 'file') {
|
||||
continue;
|
||||
}
|
||||
$params[$data->key] = $data->value;
|
||||
$output[$key] = $data['value'];
|
||||
}
|
||||
$output[] = http_build_query($params);
|
||||
return $output;
|
||||
default:
|
||||
return ["\t$this->body"];
|
||||
return [$this->body];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws EmptyHttpVerbException
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
@@ -68,15 +69,26 @@ class WgetRequest extends AbstractRequest
|
||||
[
|
||||
'wget \ ',
|
||||
"\t--no-check-certificate \ ",
|
||||
"\t--quiet \ ",
|
||||
"\t--timeout=0 \ ",
|
||||
"\t--timeout 0 \ ",
|
||||
"\t--method $this->verb \ ",
|
||||
],
|
||||
$this->prepareHeaders(),
|
||||
$this->prepareBody()
|
||||
);
|
||||
$output[] = rtrim(array_pop($output), '\ ');
|
||||
$output[] = "\t'$this->url'";
|
||||
if ($this->getBodymode() === 'formdata') {
|
||||
if ($this->getBody()) {
|
||||
if ($this->getVerb() === 'GET') {
|
||||
$output[] = sprintf("\t%s?%s", $this->getUrl(), http_build_query($this->prepareBody()));
|
||||
} else {
|
||||
$output[] = sprintf("\t--body-data '%s' \ ", http_build_query($this->prepareBody()));
|
||||
$output[] = sprintf("\t%s", $this->getUrl());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($this->getVerb() !== 'GET') {
|
||||
$output[] = sprintf("\t--body-data '%s' \ ", implode("\n", $this->prepareBody()));
|
||||
$output[] = sprintf("\t%s", $this->getUrl());
|
||||
}
|
||||
}
|
||||
return implode(PHP_EOL, array_merge($output, ['']));
|
||||
}
|
||||
}
|
||||
@@ -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["{{{$var->key}}}"] = $var->value;
|
||||
if (!empty($env->values)) {
|
||||
foreach ($env->values as $var) {
|
||||
$this->vars[static::formatKey($var->key)] = $var->value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +38,7 @@ class Environment implements \ArrayAccess
|
||||
*/
|
||||
public function offsetExists(mixed $offset): bool
|
||||
{
|
||||
return array_key_exists($offset, $this->vars);
|
||||
return array_key_exists(static::formatKey($offset), $this->vars);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,7 +46,7 @@ class Environment implements \ArrayAccess
|
||||
*/
|
||||
public function offsetGet(mixed $offset): mixed
|
||||
{
|
||||
return $this->vars[$offset];
|
||||
return $this->vars[static::formatKey($offset)] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,7 +54,7 @@ class Environment implements \ArrayAccess
|
||||
*/
|
||||
public function offsetSet(mixed $offset, mixed $value): void
|
||||
{
|
||||
$this->vars[$offset] = $value;
|
||||
$this->vars[static::formatKey($offset)] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,6 +62,17 @@ class Environment implements \ArrayAccess
|
||||
*/
|
||||
public function offsetUnset(mixed $offset): void
|
||||
{
|
||||
unset($this->vars[$offset]);
|
||||
unset($this->vars[static::formatKey($offset)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns correct variable {{name}}
|
||||
*
|
||||
* @param string $key
|
||||
* @return string
|
||||
*/
|
||||
public static function formatKey(string $key): string
|
||||
{
|
||||
return sprintf('{{%s}}', str_replace(['{', '}'], '', $key));
|
||||
}
|
||||
}
|
||||
|
||||
11
src/Exceptions/EmptyHttpVerbException.php
Normal file
11
src/Exceptions/EmptyHttpVerbException.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class EmptyHttpVerbException extends Exception
|
||||
{
|
||||
}
|
||||
11
src/Exceptions/EmptyURLException.php
Normal file
11
src/Exceptions/EmptyURLException.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class EmptyURLException extends Exception
|
||||
{
|
||||
}
|
||||
11
src/Exceptions/InvalidHttpVersionException.php
Normal file
11
src/Exceptions/InvalidHttpVersionException.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class InvalidHttpVersionException extends Exception
|
||||
{
|
||||
}
|
||||
@@ -1,222 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Exporters\Abstract;
|
||||
|
||||
use PmConverter\Exporters\Http\HttpRequest;
|
||||
use PmConverter\Exporters\RequestContract;
|
||||
|
||||
/**
|
||||
* Class to determine file content with any request format
|
||||
*/
|
||||
abstract class AbstractRequest implements RequestContract
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $http = 'HTTP/1.1'; //TODO proto
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $name;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected ?string $description = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected array $headers = [];
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected mixed $body = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $bodymode = 'raw';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $verb;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $url;
|
||||
|
||||
/**
|
||||
* Sets name from collection item to request object
|
||||
*
|
||||
* @param string $name
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public function setName(string $name): static
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns name of request
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return str_replace(DIRECTORY_SEPARATOR, '_', $this->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets description from collection item to request object
|
||||
*
|
||||
* @param string|null $description
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public function setDescription(?string $description): static
|
||||
{
|
||||
$this->description = $description;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets HTTP verb from collection item to request object
|
||||
*
|
||||
* @param string $verb
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public function setVerb(string $verb): static
|
||||
{
|
||||
$this->verb = $verb;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets URL from collection item to request object
|
||||
*
|
||||
* @param string $url
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public function setUrl(string $url): static
|
||||
{
|
||||
$this->url = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets headers from collection item to request object
|
||||
*
|
||||
* @param object[]|null $headers
|
||||
* @return $this
|
||||
*/
|
||||
public function setHeaders(?array $headers): static
|
||||
{
|
||||
foreach ($headers as $header) {
|
||||
$this->headers[$header->key] = [
|
||||
'value' => $header->value,
|
||||
'disabled' => $header?->disabled ?? false,
|
||||
];
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets authorization headers
|
||||
*
|
||||
* @param object|null $auth
|
||||
* @return $this
|
||||
*/
|
||||
public function setAuth(?object $auth): static
|
||||
{
|
||||
if (!empty($auth)) {
|
||||
switch ($auth->type) {
|
||||
case 'bearer':
|
||||
$this->headers['Authorization'] = [
|
||||
'value' => 'Bearer ' . $auth->{$auth->type}[0]->value,
|
||||
'disabled' => false,
|
||||
];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets body mode from collection item to request object
|
||||
*
|
||||
* @param string $bodymode
|
||||
* @return HttpRequest
|
||||
*/
|
||||
public function setBodymode(string $bodymode): static
|
||||
{
|
||||
$this->bodymode = $bodymode;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets body from collection item to request object
|
||||
*
|
||||
* @param object $body
|
||||
* @return $this
|
||||
*/
|
||||
public function setBody(object $body): static
|
||||
{
|
||||
$this->setBodymode($body->mode);
|
||||
if (!empty($body->options) && $body->options->{$this->bodymode}->language === 'json') {
|
||||
empty($this->headers['Content-Type']) && $this->setHeaders([
|
||||
(object)[
|
||||
'key' => 'Content-Type',
|
||||
'value' => 'application/json',
|
||||
'disabled' => false,
|
||||
],
|
||||
]);
|
||||
}
|
||||
$body->mode === 'formdata' && $this->setHeaders([
|
||||
(object)[
|
||||
'key' => 'Content-Type',
|
||||
'value' => 'multipart/form-data',
|
||||
'disabled' => false,
|
||||
],
|
||||
]);
|
||||
$this->body = $body->{$body->mode};
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array of description lines
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function prepareDescription(): array;
|
||||
|
||||
/**
|
||||
* Returns array of headers
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function prepareHeaders(): array;
|
||||
|
||||
/**
|
||||
* Returns array of request body lines
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function prepareBody(): array;
|
||||
|
||||
/**
|
||||
* Converts request object to string to be written in result file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function __toString(): string;
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Exporters;
|
||||
|
||||
|
||||
use PmConverter\Exporters\Curl\CurlConverter;
|
||||
use PmConverter\Exporters\Http\HttpConverter;
|
||||
use PmConverter\Exporters\Wget\WgetConverter;
|
||||
|
||||
enum ConvertFormat: string
|
||||
{
|
||||
case Http = HttpConverter::class;
|
||||
case Curl = CurlConverter::class;
|
||||
case Wget = WgetConverter::class;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Exporters;
|
||||
|
||||
interface ConverterContract
|
||||
{
|
||||
public function convert(object $collection, string $outputPath): void;
|
||||
public function getOutputPath(): string;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter\Exporters;
|
||||
|
||||
interface RequestContract
|
||||
{
|
||||
public function setName(string $name): static;
|
||||
public function getName(): string;
|
||||
public function setDescription(?string $description): static;
|
||||
public function setVerb(string $verb): static;
|
||||
public function setUrl(string $url): static;
|
||||
public function setAuth(object $auth): static;
|
||||
public function setHeaders(?array $headers): static;
|
||||
public function setBodymode(string $bodymode): static;
|
||||
public function setBody(object $body): static;
|
||||
public function __toString(): string;
|
||||
}
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace PmConverter;
|
||||
|
||||
use JsonException;
|
||||
use PmConverter\Exceptions\{
|
||||
CannotCreateDirectoryException,
|
||||
DirectoryIsNotReadableException,
|
||||
@@ -110,16 +111,14 @@ class FileSystem
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
* @throws JsonException
|
||||
*/
|
||||
public static function isCollectionFile(string $path): bool
|
||||
{
|
||||
$path = static::normalizePath($path);
|
||||
return !empty($path = trim($path))
|
||||
return (!empty($path = trim(static::normalizePath($path))))
|
||||
&& str_ends_with($path, '.postman_collection.json')
|
||||
&& file_exists($path)
|
||||
&& is_readable($path)
|
||||
&& ($json = json_decode(file_get_contents($path), true))
|
||||
&& json_last_error() === JSON_ERROR_NONE
|
||||
&& isset($json['collection']['info']['name']);
|
||||
&& Collection::fromFile($path)->version() !== CollectionVersion::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
21
src/HttpVersion.php
Normal file
21
src/HttpVersion.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PmConverter;
|
||||
|
||||
enum HttpVersion: string
|
||||
{
|
||||
case Version10 = '1.0';
|
||||
case Version11 = '1.1';
|
||||
case Version2 = '2';
|
||||
case Version3 = '3';
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_combine(
|
||||
array_column(self::cases(), 'name'),
|
||||
array_column(self::cases(), 'value'),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -7,22 +7,21 @@ namespace PmConverter;
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use JsonException;
|
||||
use PmConverter\Exceptions\CannotCreateDirectoryException;
|
||||
use PmConverter\Exceptions\DirectoryIsNotReadableException;
|
||||
use PmConverter\Exceptions\DirectoryIsNotWriteableException;
|
||||
use PmConverter\Exceptions\DirectoryNotExistsException;
|
||||
use PmConverter\Exporters\ConverterContract;
|
||||
use PmConverter\Exporters\ConvertFormat;
|
||||
use PmConverter\Converters\{
|
||||
ConverterContract,
|
||||
ConvertFormat};
|
||||
use PmConverter\Exceptions\{
|
||||
CannotCreateDirectoryException,
|
||||
DirectoryIsNotReadableException,
|
||||
DirectoryIsNotWriteableException,
|
||||
DirectoryNotExistsException};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Processor
|
||||
{
|
||||
/**
|
||||
* Converter version
|
||||
*/
|
||||
public const VERSION = '1.2.1';
|
||||
public const VERSION = '1.5.0';
|
||||
|
||||
/**
|
||||
* @var string[] Paths to collection files
|
||||
@@ -39,6 +38,11 @@ class Processor
|
||||
*/
|
||||
protected bool $preserveOutput = false;
|
||||
|
||||
/**
|
||||
* @var string[] Additional variables
|
||||
*/
|
||||
protected array $vars;
|
||||
|
||||
/**
|
||||
* @var ConvertFormat[] Formats to convert a collections into
|
||||
*/
|
||||
@@ -50,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 = [];
|
||||
|
||||
@@ -65,7 +69,7 @@ class Processor
|
||||
protected int $initRam;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @var string Path to environment file
|
||||
*/
|
||||
protected string $envFile;
|
||||
|
||||
@@ -89,9 +93,7 @@ class Processor
|
||||
* Parses an array of arguments came from cli
|
||||
*
|
||||
* @return void
|
||||
* @throws DirectoryIsNotWriteableException
|
||||
* @throws DirectoryNotExistsException
|
||||
* @throws DirectoryIsNotReadableException
|
||||
* @throws JsonException
|
||||
*/
|
||||
protected function parseArgs(): void
|
||||
{
|
||||
@@ -106,7 +108,7 @@ class Processor
|
||||
$normpath = FileSystem::normalizePath($rawpath);
|
||||
if (!FileSystem::isCollectionFile($normpath)) {
|
||||
throw new InvalidArgumentException(
|
||||
sprintf("this is not a valid collection file:%s\t%s %s", PHP_EOL, $arg, $rawpath)
|
||||
sprintf("not a valid collection:%s\t%s %s", PHP_EOL, $arg, $rawpath)
|
||||
);
|
||||
}
|
||||
$this->collectionPaths[] = $this->argv[$idx + 1];
|
||||
@@ -155,6 +157,26 @@ class Processor
|
||||
$this->formats[ConvertFormat::Wget->name] = ConvertFormat::Wget;
|
||||
break;
|
||||
|
||||
case '--v2.0':
|
||||
$this->formats[ConvertFormat::Postman20->name] = ConvertFormat::Postman20;
|
||||
break;
|
||||
|
||||
case '--v2.1':
|
||||
$this->formats[ConvertFormat::Postman21->name] = ConvertFormat::Postman21;
|
||||
break;
|
||||
|
||||
case '-a':
|
||||
case '--all':
|
||||
foreach (ConvertFormat::cases() as $format) {
|
||||
$this->formats[$format->name] = $format;
|
||||
}
|
||||
break;
|
||||
|
||||
case '--var':
|
||||
[$var, $value] = explode('=', trim($this->argv[$idx + 1]));
|
||||
$this->vars[$var] = $value;
|
||||
break;
|
||||
|
||||
case '-v':
|
||||
case '--version':
|
||||
die(implode(PHP_EOL, $this->version()) . PHP_EOL);
|
||||
@@ -202,6 +224,7 @@ class Processor
|
||||
foreach ($this->formats as $type) {
|
||||
$this->converters[$type->name] = new $type->value($this->preserveOutput);
|
||||
}
|
||||
unset($this->formats);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -212,13 +235,10 @@ class Processor
|
||||
protected function initCollections(): void
|
||||
{
|
||||
foreach ($this->collectionPaths as $collectionPath) {
|
||||
$content = file_get_contents(FileSystem::normalizePath($collectionPath));
|
||||
$content = json_decode($content, flags: JSON_THROW_ON_ERROR);
|
||||
if (!property_exists($content, 'collection') || empty($content?->collection)) {
|
||||
throw new JsonException("not a valid collection: $collectionPath");
|
||||
}
|
||||
$this->collections[$content->collection->info->name] = $content->collection;
|
||||
$collection = Collection::fromFile($collectionPath);
|
||||
$this->collections[$collection->name()] = $collection;
|
||||
}
|
||||
unset($this->collectionPaths, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -229,12 +249,19 @@ class Processor
|
||||
*/
|
||||
protected function initEnv(): void
|
||||
{
|
||||
if (!isset($this->envFile)) {
|
||||
return;
|
||||
}
|
||||
$content = file_get_contents(FileSystem::normalizePath($this->envFile));
|
||||
$content = json_decode($content, flags: JSON_THROW_ON_ERROR);
|
||||
if (!property_exists($content, 'environment') || empty($content?->environment)) {
|
||||
throw new JsonException("not a valid environment: $this->envFile");
|
||||
}
|
||||
$this->env = new Environment($content->environment);
|
||||
foreach ($this->vars as $var => $value) {
|
||||
$this->env[$var] = $value;
|
||||
}
|
||||
unset($this->vars, $this->envFile, $content, $var, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -268,6 +295,7 @@ class Processor
|
||||
print(PHP_EOL);
|
||||
++$success;
|
||||
}
|
||||
unset($this->converters, $type, $exporter, $outputPath, $this->collections, $collectionName, $collection);
|
||||
$this->printStats($success, $current);
|
||||
}
|
||||
|
||||
@@ -281,8 +309,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 %.3f MiB RAM', $success, $count, $time, $ram);
|
||||
printf("Converted %d/%d in %.2f $timeFmt using up to %.2f MiB RAM%s", $success, $count, $time, $ram, PHP_EOL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -317,29 +350,32 @@ class Processor
|
||||
"\t./vendor/bin/pm-convert -f|-d PATH -o OUTPUT_PATH [ARGUMENTS] [FORMATS]",
|
||||
'',
|
||||
'Possible ARGUMENTS:',
|
||||
"\t-f, --file - a PATH to single collection located in PATH to convert from",
|
||||
"\t-d, --dir - a directory with collections located in COLLECTION_FILEPATH to convert from",
|
||||
"\t-o, --output - a directory OUTPUT_PATH to put results in",
|
||||
"\t-e, --env - use environment file with variable values to replace in request",
|
||||
"\t-p, --preserve - do not delete OUTPUT_PATH (if exists)",
|
||||
"\t-h, --help - show this help message and exit",
|
||||
"\t-v, --version - show version info and exit",
|
||||
"\t-f, --file - a PATH to a single collection file to convert from",
|
||||
"\t-d, --dir - a PATH to a directory with collections to convert from",
|
||||
"\t-o, --output - a directory OUTPUT_PATH to put results in",
|
||||
"\t-e, --env - use environment file with variables to replace in requests",
|
||||
"\t--var \"NAME=VALUE\" - force replace specified env variable called NAME with custom VALUE",
|
||||
"\t-p, --preserve - do not delete OUTPUT_PATH (if exists)",
|
||||
"\t-h, --help - show this help message and exit",
|
||||
"\t-v, --version - show version info and exit",
|
||||
'',
|
||||
'If no ARGUMENTS passed then --help implied.',
|
||||
'If both -f and -d are specified then only unique set of files will be converted.',
|
||||
'If both -f and -d are specified then only unique set of files from both arguments will be converted.',
|
||||
'-f or -d are required to be specified at least once, but each may be specified multiple times.',
|
||||
'PATH must be a valid path to readable json-file or directory.',
|
||||
'OUTPUT_PATH must be a valid path to writeable directory.',
|
||||
'If -o is specified several times then only last one will be used.',
|
||||
'If -e is specified several times then only last one will be used.',
|
||||
'If -e is not specified then only collection vars will be replaced (if any).',
|
||||
'If -o or -e was specified several times then only last one will be used.',
|
||||
'',
|
||||
'Possible FORMATS:',
|
||||
"\t--http - generate raw *.http files (default)",
|
||||
"\t--curl - generate shell scripts with curl command",
|
||||
"\t--wget - generate shell scripts with wget command",
|
||||
"\t--http - generate raw *.http files (default)",
|
||||
"\t--curl - generate shell scripts with curl command",
|
||||
"\t--wget - generate shell scripts with wget command",
|
||||
"\t--v2.0 - convert from Postman Collection Schema v2.1 into v2.0",
|
||||
"\t--v2.1 - convert from Postman Collection Schema v2.0 into v2.1",
|
||||
"\t-a, --all - convert to all of formats listed above",
|
||||
'',
|
||||
'If no FORMATS specified then --http implied.',
|
||||
'Any of FORMATS can be specified at the same time.',
|
||||
'Any of FORMATS can be specified at the same time or replaced by --all.',
|
||||
'',
|
||||
'Example:',
|
||||
" ./pm-convert \ ",
|
||||
@@ -348,7 +384,9 @@ class Processor
|
||||
" --file ~/dir2/second.postman_collection.json \ ",
|
||||
" --env ~/localhost.postman_environment.json \ ",
|
||||
" -d ~/personal \ ",
|
||||
" -o ~/postman_export ",
|
||||
" --var \"myvar=some value\" \ ",
|
||||
" -o ~/postman_export \ ",
|
||||
" --all",
|
||||
"",
|
||||
], $this->copyright());
|
||||
}
|
||||
|
||||
297
tests/AbstractRequestTest.php
Normal file
297
tests/AbstractRequestTest.php
Normal file
@@ -0,0 +1,297 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PmConverter\Exceptions\{
|
||||
EmptyHttpVerbException,
|
||||
InvalidHttpVersionException};
|
||||
|
||||
class AbstractRequestTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\HttpVersion
|
||||
* @return void
|
||||
* @throws InvalidHttpVersionException
|
||||
*/
|
||||
public function testHttpVersion(): void
|
||||
{
|
||||
$request = new \PmConverter\Converters\Http\HttpRequest();
|
||||
$request->setHttpVersion(2.0);
|
||||
|
||||
$this->assertSame(2.0, $request->getHttpVersion());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::getVerb()
|
||||
* @covers PmConverter\HttpVersion
|
||||
* @return void
|
||||
* @throws InvalidHttpVersionException
|
||||
*/
|
||||
public function testInvalidHttpVersionException(): void
|
||||
{
|
||||
$this->expectException(InvalidHttpVersionException::class);
|
||||
|
||||
$request = new \PmConverter\Converters\Http\HttpRequest();
|
||||
$request->setHttpVersion(5);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::setVerb()
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::getVerb()
|
||||
* @return void
|
||||
* @throws EmptyHttpVerbException
|
||||
*/
|
||||
public function testVerb(): void
|
||||
{
|
||||
$request = new \PmConverter\Converters\Http\HttpRequest();
|
||||
$request->setVerb('GET');
|
||||
|
||||
$this->assertSame('GET', $request->getVerb());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::getVerb()
|
||||
* @return void
|
||||
* @throws EmptyHttpVerbException
|
||||
*/
|
||||
public function testEmptyHttpVerbException(): void
|
||||
{
|
||||
$this->expectException(EmptyHttpVerbException::class);
|
||||
|
||||
$request = new \PmConverter\Converters\Http\HttpRequest();
|
||||
$request->getVerb();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::setUrl()
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::getUrl()
|
||||
* @return void
|
||||
*/
|
||||
public function testUrl(): void
|
||||
{
|
||||
$request = new \PmConverter\Converters\Http\HttpRequest();
|
||||
$request->setUrl('http://localhost');
|
||||
|
||||
$this->assertSame('http://localhost', $request->getUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::setName()
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::getName()
|
||||
* @return void
|
||||
*/
|
||||
public function testName(): void
|
||||
{
|
||||
$request = new \PmConverter\Converters\Http\HttpRequest();
|
||||
$request->setName('lorem ipsum');
|
||||
|
||||
$this->assertSame('lorem ipsum', $request->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::setDescription()
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::getDescription()
|
||||
* @return void
|
||||
*/
|
||||
public function testDescription(): void
|
||||
{
|
||||
$request = new \PmConverter\Converters\Http\HttpRequest();
|
||||
$request->setDescription("lorem ipsum\ndolor sit\namet");
|
||||
|
||||
$this->assertSame("lorem ipsum\ndolor sit\namet", $request->getDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::setBodymode()
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::getBodymode()
|
||||
* @return void
|
||||
*/
|
||||
public function testBodyMode(): void
|
||||
{
|
||||
$request = new \PmConverter\Converters\Http\HttpRequest();
|
||||
$request->setBodymode('raw');
|
||||
|
||||
$this->assertSame('raw', $request->getBodymode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::setHeaders()
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::setHeader()
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::getHeaders()
|
||||
* @return void
|
||||
*/
|
||||
public function testHeaders(): void
|
||||
{
|
||||
$headers = [
|
||||
(object)[
|
||||
'key' => 'Header 1',
|
||||
'value' => 'Value 1',
|
||||
'disabled' => true,
|
||||
],
|
||||
(object)[
|
||||
'key' => 'Header 2',
|
||||
'value' => 'Value 2',
|
||||
'disabled' => false,
|
||||
],
|
||||
(object)[
|
||||
'key' => 'Header 3',
|
||||
'value' => 'Value 3',
|
||||
],
|
||||
];
|
||||
$expected = [
|
||||
'Header 1' => [
|
||||
'value' => 'Value 1',
|
||||
'disabled' => true,
|
||||
],
|
||||
'Header 2' => [
|
||||
'value' => 'Value 2',
|
||||
'disabled' => false,
|
||||
],
|
||||
'Header 3' => [
|
||||
'value' => 'Value 3',
|
||||
'disabled' => false,
|
||||
],
|
||||
'Header 4' => [
|
||||
'value' => 'Value 4',
|
||||
'disabled' => false,
|
||||
],
|
||||
'Header 5' => [
|
||||
'value' => 'Value 5',
|
||||
'disabled' => true,
|
||||
],
|
||||
];
|
||||
|
||||
$request = new \PmConverter\Converters\Http\HttpRequest();
|
||||
$request->setHeaders($headers)
|
||||
->setHeader('Header 4', 'Value 4')
|
||||
->setHeader('Header 5', 'Value 5', true);
|
||||
|
||||
$this->assertSame($expected, $request->getHeaders());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::setAuth()
|
||||
* @return void
|
||||
*/
|
||||
public function testAuthBearer(): void
|
||||
{
|
||||
$auth = (object)[
|
||||
'type' => 'bearer',
|
||||
'bearer' => [
|
||||
(object)[
|
||||
'key' => 'token',
|
||||
'value' => 'qwerty',
|
||||
'type' => 'string',
|
||||
]
|
||||
]
|
||||
];
|
||||
$expected = [
|
||||
'Authorization' => [
|
||||
'value' => 'Bearer qwerty',
|
||||
'disabled' => false,
|
||||
],
|
||||
];
|
||||
|
||||
$request = new \PmConverter\Converters\Http\HttpRequest();
|
||||
$request->setAuth($auth);
|
||||
|
||||
$this->assertSame($expected, $request->getHeaders());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::setBodymode()
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::setHeader()
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::setBody()
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::setBodyAsIs()
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::getBody()
|
||||
* @return void
|
||||
*/
|
||||
public function testJson(): void
|
||||
{
|
||||
$body = (object)[
|
||||
'mode' => 'raw',
|
||||
'raw' => $expectedBody = '["lorem ipsum dolor sit amet"]',
|
||||
'options' => (object)[
|
||||
'raw' => (object)[
|
||||
'language' => 'json',
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$request = new \PmConverter\Converters\Http\HttpRequest();
|
||||
$request->setBody($body);
|
||||
|
||||
$expectedHeaders = [
|
||||
'Content-Type' => [
|
||||
'value' => 'application/json',
|
||||
'disabled' => false,
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertSame($expectedHeaders, $request->getHeaders());
|
||||
$this->assertSame($expectedBody, $request->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::setBodymode
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::setHeader
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::setBody
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::setFormdataBody
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest::getBody
|
||||
* @return void
|
||||
*/
|
||||
public function testFormdata(): void
|
||||
{
|
||||
$body = (object)[
|
||||
'mode' => 'formdata',
|
||||
'formdata' => [
|
||||
(object)[
|
||||
'key' => 'param1',
|
||||
'value' => 'value1',
|
||||
'type' => 'text',
|
||||
],
|
||||
(object)[
|
||||
'key' => 'param2',
|
||||
'src' => '/tmp/somefile.txt',
|
||||
'type' => 'file',
|
||||
],
|
||||
],
|
||||
];
|
||||
$expectedBody = [
|
||||
'param1' => [
|
||||
'value' => 'value1',
|
||||
'type' => 'text',
|
||||
],
|
||||
'param2' => [
|
||||
'value' => '/tmp/somefile.txt',
|
||||
'type' => 'file',
|
||||
],
|
||||
];
|
||||
$expectedHeaders = [
|
||||
'Content-Type' => [
|
||||
'value' => 'multipart/form-data',
|
||||
'disabled' => false,
|
||||
],
|
||||
];
|
||||
|
||||
$request = new \PmConverter\Converters\Http\HttpRequest();
|
||||
$request->setBody($body);
|
||||
|
||||
$this->assertSame($expectedHeaders, $request->getHeaders());
|
||||
$this->assertSame($expectedBody, $request->getBody());
|
||||
}
|
||||
}
|
||||
140
tests/HttpRequestTest.php
Normal file
140
tests/HttpRequestTest.php
Normal file
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PmConverter\Converters\Http\HttpRequest;
|
||||
|
||||
class HttpRequestTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Http\HttpRequest
|
||||
* @covers PmConverter\Converters\Http\HttpRequest::prepareDescription()
|
||||
* @covers PmConverter\Converters\Http\HttpRequest::__toString()
|
||||
* @return void
|
||||
*/
|
||||
public function testPrepareDescription()
|
||||
{
|
||||
$description = [
|
||||
'lorem ipsum',
|
||||
'dolor sit',
|
||||
'amet',
|
||||
];
|
||||
$needle = implode("\n", [
|
||||
'# lorem ipsum',
|
||||
'# dolor sit',
|
||||
'# amet',
|
||||
]);
|
||||
|
||||
$request = (new HttpRequest())
|
||||
->setVerb('GET')
|
||||
->setUrl('http://localhost')
|
||||
->setDescription(implode("\n", $description));
|
||||
|
||||
$this->assertStringContainsString($needle, (string)$request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Http\HttpRequest
|
||||
* @covers PmConverter\Converters\Http\HttpRequest::prepareHeaders()
|
||||
* @covers PmConverter\Converters\Http\HttpRequest::__toString()
|
||||
* @return void
|
||||
*/
|
||||
public function testPrepareHeaders()
|
||||
{
|
||||
$headers = [
|
||||
(object)[
|
||||
'key' => 'Header1',
|
||||
'value' => 'Value 1',
|
||||
'disabled' => true,
|
||||
],
|
||||
(object)[
|
||||
'key' => 'Header2',
|
||||
'value' => 'Value 2',
|
||||
'disabled' => false,
|
||||
],
|
||||
(object)[
|
||||
'key' => 'Header3',
|
||||
'value' => 'Value 3',
|
||||
],
|
||||
];
|
||||
$needle = implode("\n", [
|
||||
'# Header1: Value 1',
|
||||
'Header2: Value 2',
|
||||
'Header3: Value 3',
|
||||
]);
|
||||
|
||||
$request = (new HttpRequest())
|
||||
->setVerb('GET')
|
||||
->setUrl('http://localhost')
|
||||
->setHeaders($headers);
|
||||
|
||||
$this->assertStringContainsString($needle, (string)$request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Http\HttpRequest
|
||||
* @covers PmConverter\Converters\Http\HttpRequest::prepareBody()
|
||||
* @covers PmConverter\Converters\Http\HttpRequest::__toString()
|
||||
* @return void
|
||||
*/
|
||||
public function testPrepareFormdataBody()
|
||||
{
|
||||
$body = (object)[
|
||||
'mode' => 'formdata',
|
||||
'formdata' => [
|
||||
(object)[
|
||||
'key' => 'param1',
|
||||
'value' => 'value1',
|
||||
'type' => 'text',
|
||||
],
|
||||
(object)[
|
||||
'key' => 'param2',
|
||||
'src' => '/tmp/somefile.txt',
|
||||
'type' => 'file',
|
||||
],
|
||||
],
|
||||
];
|
||||
$needle = implode("\n", [
|
||||
'param1=value1',
|
||||
'param2=@/tmp/somefile.txt',
|
||||
]);
|
||||
|
||||
$request = (new HttpRequest())
|
||||
->setVerb('GET')
|
||||
->setUrl('http://localhost')
|
||||
->setBody($body);
|
||||
|
||||
$this->assertStringContainsString($needle, (string)$request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Http\HttpRequest
|
||||
* @covers PmConverter\Converters\Http\HttpRequest::prepareBody()
|
||||
* @covers PmConverter\Converters\Http\HttpRequest::__toString()
|
||||
* @return void
|
||||
*/
|
||||
public function testPrepareJsonBody()
|
||||
{
|
||||
$body = (object)[
|
||||
'mode' => 'raw',
|
||||
'raw' => $needle = '["lorem ipsum dolor sit amet"]',
|
||||
'options' => (object)[
|
||||
'raw' => (object)[
|
||||
'language' => 'json',
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$request = (new HttpRequest())
|
||||
->setVerb('GET')
|
||||
->setUrl('http://localhost')
|
||||
->setBody($body);
|
||||
|
||||
$this->assertStringContainsString($needle, (string)$request);
|
||||
}
|
||||
}
|
||||
232
tests/WgetRequestTest.php
Normal file
232
tests/WgetRequestTest.php
Normal file
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PmConverter\Converters\Wget\WgetRequest;
|
||||
|
||||
class WgetRequestTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest::prepareDescription()
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest::__toString()
|
||||
* @return void
|
||||
*/
|
||||
public function testPrepareNotEmptyDescription()
|
||||
{
|
||||
$request = (new WgetRequest())
|
||||
->setVerb('GET')
|
||||
->setUrl('http://localhost')
|
||||
->setDescription(null);
|
||||
|
||||
$result = explode("\n", (string)$request);
|
||||
|
||||
$this->assertFalse(str_starts_with($result[0], '# ') && str_starts_with($result[1], '# '));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest::prepareDescription()
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest::__toString()
|
||||
* @return void
|
||||
*/
|
||||
public function testPrepareEmptyDescription()
|
||||
{
|
||||
$description = [
|
||||
'lorem ipsum',
|
||||
'dolor sit',
|
||||
'amet',
|
||||
];
|
||||
$needle = implode("\n", [
|
||||
'# lorem ipsum',
|
||||
'# dolor sit',
|
||||
'# amet',
|
||||
]);
|
||||
|
||||
$request = (new WgetRequest())
|
||||
->setVerb('GET')
|
||||
->setUrl('http://localhost')
|
||||
->setDescription(implode("\n", $description));
|
||||
|
||||
$this->assertStringContainsString($needle, (string)$request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest::prepareHeaders()
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest::__toString()
|
||||
* @return void
|
||||
*/
|
||||
public function testPrepareHeaders()
|
||||
{
|
||||
$headers = [
|
||||
(object)[
|
||||
'key' => 'Header1',
|
||||
'value' => 'Value 1',
|
||||
'disabled' => true,
|
||||
],
|
||||
(object)[
|
||||
'key' => 'Header2',
|
||||
'value' => 'Value 2',
|
||||
'disabled' => false,
|
||||
],
|
||||
(object)[
|
||||
'key' => 'Header3',
|
||||
'value' => 'Value 3',
|
||||
],
|
||||
];
|
||||
$needle = implode("\n", [
|
||||
"\t--header 'Header2: Value 2' \ ",
|
||||
"\t--header 'Header3: Value 3' \ ",
|
||||
]);
|
||||
|
||||
$request = (new WgetRequest())
|
||||
->setVerb('GET')
|
||||
->setUrl('http://localhost')
|
||||
->setHeaders($headers);
|
||||
|
||||
$this->assertStringContainsString($needle, (string)$request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest::prepareBody()
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest::__toString()
|
||||
* @return void
|
||||
*/
|
||||
public function testPrepareFormdataBodyGet()
|
||||
{
|
||||
$body = (object)[
|
||||
'mode' => 'formdata',
|
||||
'formdata' => [
|
||||
(object)[
|
||||
'key' => 'param1',
|
||||
'value' => 'value1',
|
||||
'type' => 'text',
|
||||
],
|
||||
(object)[
|
||||
'key' => 'param2',
|
||||
'src' => '/tmp/somefile.txt',
|
||||
'type' => 'file',
|
||||
],
|
||||
(object)[
|
||||
'key' => 'param3',
|
||||
'value' => 'value3',
|
||||
'type' => 'text',
|
||||
],
|
||||
],
|
||||
];
|
||||
$needle = 'http://localhost?' . http_build_query([
|
||||
'param1' => 'value1',
|
||||
'param3' => 'value3',
|
||||
]);
|
||||
|
||||
$request = (new WgetRequest())
|
||||
->setVerb('GET')
|
||||
->setUrl('http://localhost')
|
||||
->setBody($body);
|
||||
|
||||
$this->assertStringContainsString($needle, (string)$request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest::prepareBody()
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest::__toString()
|
||||
* @return void
|
||||
*/
|
||||
public function testPrepareFormdataBodyPost()
|
||||
{
|
||||
$body = (object)[
|
||||
'mode' => 'formdata',
|
||||
'formdata' => [
|
||||
(object)[
|
||||
'key' => 'param1',
|
||||
'value' => 'value1',
|
||||
'type' => 'text',
|
||||
],
|
||||
(object)[
|
||||
'key' => 'param2',
|
||||
'src' => '/tmp/somefile.txt',
|
||||
'type' => 'file',
|
||||
],
|
||||
(object)[
|
||||
'key' => 'param3',
|
||||
'value' => 'value3',
|
||||
'type' => 'text',
|
||||
],
|
||||
],
|
||||
];
|
||||
$needle = http_build_query([
|
||||
'param1' => 'value1',
|
||||
'param3' => 'value3',
|
||||
]);
|
||||
|
||||
$request = (new WgetRequest())
|
||||
->setVerb('POST')
|
||||
->setUrl('http://localhost')
|
||||
->setBody($body);
|
||||
|
||||
$this->assertStringContainsString($needle, (string)$request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest::prepareBody()
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest::__toString()
|
||||
* @return void
|
||||
*/
|
||||
public function testPrepareJsonBodyGet()
|
||||
{
|
||||
$body = (object)[
|
||||
'mode' => 'raw',
|
||||
'raw' => $needle = '["lorem ipsum dolor sit amet"]',
|
||||
'options' => (object)[
|
||||
'raw' => (object)[
|
||||
'language' => 'json',
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$request = (new WgetRequest())
|
||||
->setVerb('GET')
|
||||
->setUrl('http://localhost')
|
||||
->setBody($body);
|
||||
|
||||
$this->assertStringNotContainsString($needle, (string)$request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers PmConverter\Converters\Abstract\AbstractRequest
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest::prepareBody()
|
||||
* @covers PmConverter\Converters\Wget\WgetRequest::__toString()
|
||||
* @return void
|
||||
*/
|
||||
public function testPrepareJsonBodyPost()
|
||||
{
|
||||
$body = (object)[
|
||||
'mode' => 'raw',
|
||||
'raw' => $needle = '["lorem ipsum dolor sit amet"]',
|
||||
'options' => (object)[
|
||||
'raw' => (object)[
|
||||
'language' => 'json',
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$request = (new WgetRequest())
|
||||
->setVerb('POST')
|
||||
->setUrl('http://localhost')
|
||||
->setBody($body);
|
||||
|
||||
$this->assertStringContainsString($needle, (string)$request);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user