diff --git a/php/postman-convert.php b/php/postman-convert.php new file mode 100644 index 0000000..2ed5fbe --- /dev/null +++ b/php/postman-convert.php @@ -0,0 +1,220 @@ +#!/bin/php +toArray(); + } elseif (method_exists($something, 'jsonSerialize')) { + $something = $something->jsonSerialize(); + } else { + $something = var_export($something, true); + } + } + $result[] = $something; + } + printf('[' . date('H:i:s') . '] ' . implode(' ', $result) . PHP_EOL); +} + +/** + * Read Postman collection file + * + * @param string $path Path to file (`~` allowed) + * @return object JSON-decoded object + * @throws Exception + */ +function read_collection_file(string $path): object +{ + $content = file_get_contents(str_replace('~/', $_SERVER['HOME'], $path)); + $json = json_decode($content); + return json_last_error() === JSON_ERROR_NONE + ? $json + : throw new Exception( + "File '$path' does not contain a valid json. Error: [" . json_last_error() . "] " . json_last_error_msg() + ); +} + +/** + * Writes data from $request as *.http-file into $dir_tree + * + * @param object $request Request data + * @param string|null $dir_tree Directory path + * @return void + */ +function write_request(object $request, ?string $dir_tree = null) +{ + $filepath = './files/' . ($dir_tree ? $dir_tree . '/' : '') . $request->name; + $httpfile = "$filepath.http"; + $mdfile = "$filepath.md"; + + // name + //file_put_contents($httpfile, "# $request->name\n\n", FILE_APPEND); + file_put_contents($mdfile, "# $request->name\n\n", FILE_APPEND); + + // description (if exists) + isset($request->request->description) && /*file_put_contents( + $httpfile, + '# ' . str_replace("\n", "\n# ", $request->request->description) . "\n\n", + FILE_APPEND + ) &&*/ file_put_contents($mdfile, "{$request->request->description}\n\n", FILE_APPEND); + + // generating request data + $url = "{$request->request->method} {$request->request->url->raw} HTTP/1.1"; + $headers = []; + $body = ''; + if (count($request->request->header) > 0) { + foreach ($request->request->header as $header) { + $headers[(empty($header->disabled) ? '' : '# ') . $header->key] = $header->value; + } + } + if (isset($request->request->body)) { + $bodymode = $request->request->body->mode; + if (($request->request->body->options->$bodymode->language ?? '') === 'json') { + empty($headers['Content-Type']) && $headers['Content-Type'] = 'application/json'; + empty($headers['Accept']) && $headers['Accept'] = 'application/json'; + } + array_walk($headers, fn(&$value, $key) => $value = $key . ': ' . $value); + switch ($bodymode) { + case 'formdata': + foreach ($request->request->body->$bodymode as $data) { + if ($data->type === 'file' && !empty($data->src)) { + foreach ($data->src as $src) { + $body .= (empty($data->disabled) ? '' : '# ') . "$data->key=$src\n"; + } + } else { + $body .= (empty($data->disabled) ? '' : '# ') . "$data->key=$data->value\n"; + } + } + break; + default: + $body = $request->request->body->$bodymode; + } + } + $headers = trim(implode("\n", $headers)); + $body = trim($body); + file_put_contents($httpfile, trim("$url\n$headers\n\n$body\n"), FILE_APPEND); + file_put_contents($mdfile, "```\n" . trim("$url\n$headers\n\n$body") . "\n```", FILE_APPEND); + + // response examples + if (!empty($request->response)) { + file_put_contents($mdfile, "\n# Examples\n", FILE_APPEND); + foreach ($request->response as $response) { + file_put_contents($mdfile, "## $response->name\n```\n$url\n", FILE_APPEND); + foreach ($response->header as $header) { + file_put_contents($mdfile, "$header->key=$header->value\n", FILE_APPEND); + } + file_put_contents($mdfile, "\n$body\n```\nResult:\n```\n$response->body\n```\n", FILE_APPEND); + } + } + + out('[OK] ' . $httpfile); +} + +/** + * Processes one item in Postman collection + * If $item is nested directory then function processes it recursively, otherwise writes *.http-file + * + * @param $item + * @return void + */ +function process_item($item = null) +{ + if (empty($item)) { + return; + } + if (is_array($item)) { + static $dir_tree; + static $path; + foreach ($item as $subitem) { + if (empty($subitem->item)) { + write_request($subitem, $path); + } else { + $dir_tree[] = $subitem->name; + $path = implode('/', $dir_tree); + !file_exists('./files/' . $path) && mkdir('./files/' . $path); + isset($subitem->description) && file_put_contents( + './files/' . $path . '/README.md', + $subitem->description + ); + process_item($subitem->item); + array_pop($dir_tree); + $path = implode('/', $dir_tree); + } + } + } else { + write_request($item, ''); + } +} + +/** + * Recursively removes directory + * + * @param string $path + * @return void + */ +function remove_directory(string $path): void +{ + $files = glob($path . '/*'); + foreach ($files as $file) { + is_dir($file) ? remove_directory($file) : unlink($file); + } + rmdir($path); +} + +try { + remove_directory('./files'); + !file_exists('./files/') && mkdir('./files/'); + $json = read_collection_file($argv[1] ?? throw new Exception('ERROR: No collection file specified')); + process_item($json->item); +} catch (Exception $e) { + out($e->getMessage()); + return 1; +}