mirror of
https://github.com/bitinflow/expose.git
synced 2026-03-13 21:45:55 +00:00
wip
This commit is contained in:
@@ -12,6 +12,7 @@ class Client
|
||||
protected $loop;
|
||||
protected $host;
|
||||
protected $port;
|
||||
public static $subdomains = [];
|
||||
|
||||
public function __construct(LoopInterface $loop, $host, $port)
|
||||
{
|
||||
@@ -31,6 +32,7 @@ class Client
|
||||
$connection->authenticate($sharedUrl, $subdomain);
|
||||
|
||||
$clientConnection->on('authenticated', function ($data) {
|
||||
static::$subdomains[] = "$data->subdomain.{$this->host}:{$this->port}";
|
||||
dump("Connected to http://$data->subdomain.{$this->host}:{$this->port}");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -71,4 +71,11 @@ class Connection
|
||||
],
|
||||
]));
|
||||
}
|
||||
|
||||
public function ping()
|
||||
{
|
||||
$this->socket->write(json_encode([
|
||||
'event' => 'pong',
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
namespace App\Client;
|
||||
|
||||
use App\HttpServer\App;
|
||||
use App\HttpServer\Controllers\AttachDataToLogController;
|
||||
use App\HttpServer\Controllers\ClearLogsController;
|
||||
use App\HttpServer\Controllers\DashboardController;
|
||||
use App\HttpServer\Controllers\LogController;
|
||||
use App\HttpServer\Controllers\ReplayLogController;
|
||||
@@ -67,6 +69,8 @@ class Factory
|
||||
$logRoute = new Route('/logs', ['_controller' => new LogController()], [], [], null, [], ['GET']);
|
||||
$storeLogRoute = new Route('/logs', ['_controller' => new StoreLogController()], [], [], null, [], ['POST']);
|
||||
$replayLogRoute = new Route('/replay/{log}', ['_controller' => new ReplayLogController()], [], [], null, [], ['GET']);
|
||||
$attachLogDataRoute = new Route('/logs/{request_id}/data', ['_controller' => new AttachDataToLogController()], [], [], null, [], ['POST']);
|
||||
$clearLogsRoute = new Route('/logs/clear', ['_controller' => new ClearLogsController()], [], [], null, [], ['GET']);
|
||||
|
||||
$this->app->route('/socket', new WsServer(new Socket()), ['*']);
|
||||
|
||||
@@ -74,19 +78,32 @@ class Factory
|
||||
$this->app->routes->add('logs', $logRoute);
|
||||
$this->app->routes->add('storeLogs', $storeLogRoute);
|
||||
$this->app->routes->add('replayLog', $replayLogRoute);
|
||||
$this->app->routes->add('attachLogData', $attachLogDataRoute);
|
||||
$this->app->routes->add('clearLogs', $clearLogsRoute);
|
||||
}
|
||||
|
||||
protected function detectNextFreeDashboardPort($port = 4040): int
|
||||
{
|
||||
while (is_resource(@fsockopen('127.0.0.1', $port))) {
|
||||
$port++;
|
||||
}
|
||||
|
||||
return $port;
|
||||
}
|
||||
|
||||
public function createHttpServer()
|
||||
{
|
||||
$this->loop->futureTick(function () {
|
||||
$dashboardUrl = 'http://127.0.0.1:4040/';
|
||||
$dashboardPort = $this->detectNextFreeDashboardPort();
|
||||
|
||||
echo('Started Dashboard on port 4040'. PHP_EOL);
|
||||
$this->loop->futureTick(function () use ($dashboardPort) {
|
||||
$dashboardUrl = "http://127.0.0.1:{$dashboardPort}/";
|
||||
|
||||
echo('If the dashboard does not automatically open, visit: '.$dashboardUrl . PHP_EOL);
|
||||
echo("Started Dashboard on port {$dashboardPort}" . PHP_EOL);
|
||||
|
||||
echo('If the dashboard does not automatically open, visit: ' . $dashboardUrl . PHP_EOL);
|
||||
});
|
||||
|
||||
$this->app = new App('127.0.0.1', 4040, '0.0.0.0', $this->loop);
|
||||
$this->app = new App('127.0.0.1', $dashboardPort, '0.0.0.0', $this->loop);
|
||||
|
||||
$this->addRoutes();
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Commands;
|
||||
use App\Server\Factory;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use LaravelZero\Framework\Commands\Command;
|
||||
use React\EventLoop\LoopInterface;
|
||||
|
||||
class ServeCommand extends Command
|
||||
{
|
||||
@@ -15,6 +16,7 @@ class ServeCommand extends Command
|
||||
public function handle()
|
||||
{
|
||||
(new Factory())
|
||||
->setLoop(app(LoopInterface::class))
|
||||
->setHost($this->argument('host'))
|
||||
->setHostname($this->argument('hostname'))
|
||||
->createServer()
|
||||
|
||||
@@ -17,8 +17,8 @@ class ShareCommand extends Command
|
||||
{
|
||||
(new Factory())
|
||||
->setLoop(app(LoopInterface::class))
|
||||
//->setHost('beyond.sh')
|
||||
//->setPort(8080)
|
||||
->setHost('beyond.sh')
|
||||
->setPort(8080)
|
||||
->createClient($this->argument('host'), explode(',', $this->option('subdomain')))
|
||||
->createHttpServer()
|
||||
->run();
|
||||
|
||||
22
app/HttpServer/Controllers/AttachDataToLogController.php
Normal file
22
app/HttpServer/Controllers/AttachDataToLogController.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\HttpServer\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Logger\RequestLogger;
|
||||
|
||||
class AttachDataToLogController extends PostController
|
||||
{
|
||||
public function handle(Request $request)
|
||||
{
|
||||
/** @var RequestLogger $requestLogger */
|
||||
$requestLogger = app(RequestLogger::class);
|
||||
$loggedRequest = $requestLogger->findLoggedRequest($request->get('request_id', ''));
|
||||
|
||||
if (! is_null($loggedRequest)) {
|
||||
$loggedRequest->setAdditionalData((array)$request->get('data', []));
|
||||
|
||||
$requestLogger->pushLogs();
|
||||
}
|
||||
}
|
||||
}
|
||||
31
app/HttpServer/Controllers/ClearLogsController.php
Normal file
31
app/HttpServer/Controllers/ClearLogsController.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\HttpServer\Controllers;
|
||||
|
||||
use App\Client\TunnelConnection;
|
||||
use App\HttpServer\QueryParameters;
|
||||
use App\Logger\RequestLogger;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use Ratchet\ConnectionInterface;
|
||||
use function GuzzleHttp\Psr7\str;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
|
||||
class ClearLogsController extends Controller
|
||||
{
|
||||
public function onOpen(ConnectionInterface $connection, RequestInterface $request = null)
|
||||
{
|
||||
/** @var RequestLogger $logger */
|
||||
$logger = app(RequestLogger::class);
|
||||
$logger->clear();
|
||||
|
||||
$connection->send(
|
||||
str(new Response(
|
||||
200,
|
||||
['Content-Type' => 'application/json'],
|
||||
''
|
||||
))
|
||||
);
|
||||
|
||||
$connection->close();
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\HttpServer\Controllers;
|
||||
|
||||
use App\Client\Client;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use function GuzzleHttp\Psr7\str;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
@@ -15,10 +16,19 @@ class DashboardController extends Controller
|
||||
str(new Response(
|
||||
200,
|
||||
['Content-Type' => 'text/html'],
|
||||
file_get_contents(base_path('resources/views/index.html'))
|
||||
$this->getView()
|
||||
))
|
||||
);
|
||||
|
||||
$connection->close();
|
||||
}
|
||||
|
||||
protected function getView(): string
|
||||
{
|
||||
$view = file_get_contents(base_path('resources/views/index.html'));
|
||||
|
||||
$view = str_replace('%subdomains%', implode(' ', Client::$subdomains), $view);
|
||||
|
||||
return $view;
|
||||
}
|
||||
}
|
||||
|
||||
69
app/HttpServer/Controllers/PostController.php
Normal file
69
app/HttpServer/Controllers/PostController.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\HttpServer\Controllers;
|
||||
|
||||
use App\HttpServer\QueryParameters;
|
||||
use GuzzleHttp\Psr7\ServerRequest;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Ratchet\ConnectionInterface;
|
||||
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
|
||||
|
||||
abstract class PostController extends Controller
|
||||
{
|
||||
public function onOpen(ConnectionInterface $connection, RequestInterface $request = null)
|
||||
{
|
||||
$connection->contentLength = $this->findContentLength($request->getHeaders());
|
||||
|
||||
$connection->requestBuffer = (string) $request->getBody();
|
||||
|
||||
$connection->request = $request;
|
||||
|
||||
$this->checkContentLength($connection);
|
||||
}
|
||||
|
||||
public function onMessage(ConnectionInterface $from, $msg)
|
||||
{
|
||||
$from->requestBuffer .= $msg;
|
||||
|
||||
$this->checkContentLength($from);
|
||||
}
|
||||
|
||||
protected function findContentLength(array $headers): int
|
||||
{
|
||||
return Collection::make($headers)->first(function ($values, $header) {
|
||||
return strtolower($header) === 'content-length';
|
||||
})[0] ?? 0;
|
||||
}
|
||||
|
||||
protected function checkContentLength(ConnectionInterface $connection)
|
||||
{
|
||||
if (strlen($connection->requestBuffer) === $connection->contentLength) {
|
||||
$laravelRequest = $this->createLaravelRequest($connection);
|
||||
|
||||
$this->handle($laravelRequest);
|
||||
|
||||
$connection->close();
|
||||
|
||||
unset($connection->requestBuffer);
|
||||
unset($connection->contentLength);
|
||||
unset($connection->request);
|
||||
}
|
||||
}
|
||||
|
||||
abstract public function handle(Request $request);
|
||||
|
||||
protected function createLaravelRequest(ConnectionInterface $connection): Request
|
||||
{
|
||||
$serverRequest = (new ServerRequest(
|
||||
$connection->request->getMethod(),
|
||||
$connection->request->getUri(),
|
||||
$connection->request->getHeaders(),
|
||||
$connection->requestBuffer,
|
||||
$connection->request->getProtocolVersion()
|
||||
))->withQueryParams(QueryParameters::create($connection->request)->all());
|
||||
|
||||
return Request::createFromBase((new HttpFoundationFactory)->createRequest($serverRequest));
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,9 @@ use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use Laminas\Http\Request;
|
||||
use Laminas\Http\Response;
|
||||
use Namshi\Cuzzle\Formatter\CurlFormatter;
|
||||
use Riverline\MultiPartParser\StreamedPart;
|
||||
use function GuzzleHttp\Psr7\parse_request;
|
||||
|
||||
class LoggedRequest implements \JsonSerializable
|
||||
{
|
||||
@@ -35,12 +37,15 @@ class LoggedRequest implements \JsonSerializable
|
||||
/** @var string */
|
||||
protected $subdomain;
|
||||
|
||||
/** @var array */
|
||||
protected $additionalData = [];
|
||||
|
||||
public function __construct(string $rawRequest, Request $parsedRequest)
|
||||
{
|
||||
$this->id = (string)Str::uuid();
|
||||
$this->startTime = now();
|
||||
$this->rawRequest = $rawRequest;
|
||||
$this->parsedRequest = $parsedRequest;
|
||||
$this->id = $this->getRequestId();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,6 +66,8 @@ class LoggedRequest implements \JsonSerializable
|
||||
'body' => $this->isBinary($this->rawRequest) ? 'BINARY' : $this->parsedRequest->getContent(),
|
||||
'query' => $this->parsedRequest->getQuery()->toArray(),
|
||||
'post' => $this->getPost(),
|
||||
'curl' => (new CurlFormatter())->format(parse_request($this->rawRequest)),
|
||||
'additional_data' => $this->additionalData,
|
||||
],
|
||||
];
|
||||
|
||||
@@ -77,6 +84,11 @@ class LoggedRequest implements \JsonSerializable
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function setAdditionalData(array $data)
|
||||
{
|
||||
$this->additionalData = array_merge($this->additionalData, $data);
|
||||
}
|
||||
|
||||
protected function isBinary(string $string): bool
|
||||
{
|
||||
return preg_match('~[^\x20-\x7E\t\r\n]~', $string) > 0;
|
||||
@@ -174,4 +186,9 @@ class LoggedRequest implements \JsonSerializable
|
||||
{
|
||||
return Arr::get($this->parsedRequest->getHeaders()->toArray(), 'X-Original-Host');
|
||||
}
|
||||
|
||||
protected function getRequestId()
|
||||
{
|
||||
return Arr::get($this->parsedRequest->getHeaders()->toArray(), 'X-Expose-Request-ID', (string)Str::uuid());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,14 @@ class RequestLogger
|
||||
return $this->requests;
|
||||
}
|
||||
|
||||
protected function pushLogs()
|
||||
public function clear()
|
||||
{
|
||||
$this->requests = [];
|
||||
|
||||
$this->pushLogs();
|
||||
}
|
||||
|
||||
public function pushLogs()
|
||||
{
|
||||
$this
|
||||
->client
|
||||
|
||||
@@ -23,6 +23,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
|
||||
$this->app->singleton(RequestLogger::class, function () {
|
||||
$browser = new Browser(app(LoopInterface::class));
|
||||
|
||||
return new RequestLogger($browser);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -32,14 +32,17 @@ class Connection
|
||||
return array_pop($this->proxies);
|
||||
}
|
||||
|
||||
public function rewriteHostInformation($serverHost, $port, string $data)
|
||||
public function rewriteHostInformation($serverHost, $port, $requestId, string $data)
|
||||
{
|
||||
$appName = config('app.name');
|
||||
$appVersion = config('app.version');
|
||||
|
||||
$originalHost = "{$this->subdomain}.{$serverHost}:{$port}";
|
||||
|
||||
$data = preg_replace('/Host: '.$this->subdomain.'.'.$serverHost.'(.*)\r\n/', "Host: {$this->host}\r\n" .
|
||||
"X-Tunnel-By: {$appName} {$appVersion}\r\n" .
|
||||
"X-Original-Host: {$this->subdomain}.{$serverHost}:{$port}\r\n", $data);
|
||||
"X-Exposed-By: {$appName} {$appVersion}\r\n" .
|
||||
"X-Expose-Request-ID: {$requestId}\r\n" .
|
||||
"X-Original-Host: {$originalHost}\r\n", $data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use Ratchet\ConnectionInterface;
|
||||
use Ratchet\MessageComponentInterface;
|
||||
use function GuzzleHttp\Psr7\parse_request;
|
||||
|
||||
class Shaft implements MessageComponentInterface
|
||||
class Expose implements MessageComponentInterface
|
||||
{
|
||||
protected $connectionManager;
|
||||
|
||||
@@ -60,7 +60,7 @@ class Factory
|
||||
|
||||
$connectionManager = new ConnectionManager($this->hostname, $this->port);
|
||||
|
||||
$app = new Shaft($connectionManager);
|
||||
$app = new Expose($connectionManager);
|
||||
|
||||
return new IoServer($app, $socket, $this->loop);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Server\Messages;
|
||||
use App\Server\Connections\ConnectionManager;
|
||||
use Illuminate\Support\Str;
|
||||
use Ratchet\ConnectionInterface;
|
||||
use React\EventLoop\LoopInterface;
|
||||
use stdClass;
|
||||
|
||||
class ControlMessage implements Message
|
||||
@@ -45,6 +46,13 @@ class ControlMessage implements Message
|
||||
'subdomain' => $connectionInfo->subdomain,
|
||||
'client_id' => $connectionInfo->client_id
|
||||
]));
|
||||
|
||||
$loop = app(LoopInterface::class);
|
||||
$timer = $loop->addPeriodicTimer(5, function () use ($connection) {
|
||||
$connection->send(json_encode([
|
||||
'event' => 'ping'
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
protected function registerProxy(ConnectionInterface $connection, $data)
|
||||
|
||||
@@ -69,10 +69,10 @@ class TunnelMessage implements Message
|
||||
|
||||
private function copyDataToClient(Connection $clientConnection)
|
||||
{
|
||||
$data = $clientConnection->rewriteHostInformation($this->connectionManager->host(), $this->connectionManager->port(), $this->connection->buffer);
|
||||
|
||||
$requestId = uniqid();
|
||||
|
||||
$data = $clientConnection->rewriteHostInformation($this->connectionManager->host(), $this->connectionManager->port(), $requestId, $this->connection->buffer);
|
||||
|
||||
// Ask client to create a new proxy
|
||||
$clientConnection->socket->send(json_encode([
|
||||
'event' => 'createProxy',
|
||||
|
||||
@@ -22,9 +22,13 @@
|
||||
"cboden/ratchet": "^0.4.2",
|
||||
"clue/buzz-react": "^2.7",
|
||||
"guzzlehttp/guzzle": "^6.5",
|
||||
"illuminate/http": "5.8.*|^6.0|^7.0",
|
||||
"laminas/laminas-http": "^2.11",
|
||||
"laravel-zero/framework": "^7.0",
|
||||
"namshi/cuzzle": "^2.0",
|
||||
"react/socket": "^1.4",
|
||||
"symfony/http-kernel": "^4.0|^5.0",
|
||||
"symfony/psr-http-message-bridge": "^1.1|^2.0",
|
||||
"riverline/multipart-parser": "^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
@@ -53,5 +57,5 @@
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
"bin": ["phunnel"]
|
||||
"bin": ["expose"]
|
||||
}
|
||||
|
||||
673
composer.lock
generated
673
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "5fb0e746e857756290dd83192601f8ec",
|
||||
"content-hash": "f85ae104dc6c4806c3d1a158c5d182e6",
|
||||
"packages": [
|
||||
{
|
||||
"name": "bfunky/http-parser",
|
||||
@@ -659,7 +659,7 @@
|
||||
},
|
||||
{
|
||||
"name": "illuminate/cache",
|
||||
"version": "v7.4.0",
|
||||
"version": "v7.6.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/cache.git",
|
||||
@@ -710,7 +710,7 @@
|
||||
},
|
||||
{
|
||||
"name": "illuminate/config",
|
||||
"version": "v7.4.0",
|
||||
"version": "v7.6.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/config.git",
|
||||
@@ -754,7 +754,7 @@
|
||||
},
|
||||
{
|
||||
"name": "illuminate/console",
|
||||
"version": "v7.4.0",
|
||||
"version": "v7.6.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/console.git",
|
||||
@@ -808,16 +808,16 @@
|
||||
},
|
||||
{
|
||||
"name": "illuminate/container",
|
||||
"version": "v7.4.0",
|
||||
"version": "v7.6.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/container.git",
|
||||
"reference": "9108edffa95b34df94dc36721d92f380dd59bea3"
|
||||
"reference": "10c5802e360595f5f2a8b6afa176b9542851e580"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/container/zipball/9108edffa95b34df94dc36721d92f380dd59bea3",
|
||||
"reference": "9108edffa95b34df94dc36721d92f380dd59bea3",
|
||||
"url": "https://api.github.com/repos/illuminate/container/zipball/10c5802e360595f5f2a8b6afa176b9542851e580",
|
||||
"reference": "10c5802e360595f5f2a8b6afa176b9542851e580",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -848,20 +848,20 @@
|
||||
],
|
||||
"description": "The Illuminate Container package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"time": "2020-03-18T13:25:12+00:00"
|
||||
"time": "2020-04-06T13:33:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/contracts",
|
||||
"version": "v7.4.0",
|
||||
"version": "v7.6.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/contracts.git",
|
||||
"reference": "f13c89509345ceee05f3527a83f38c77c0f74579"
|
||||
"reference": "69a40779d8fc43e3f43da973b9c0c20bdbd81203"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/contracts/zipball/f13c89509345ceee05f3527a83f38c77c0f74579",
|
||||
"reference": "f13c89509345ceee05f3527a83f38c77c0f74579",
|
||||
"url": "https://api.github.com/repos/illuminate/contracts/zipball/69a40779d8fc43e3f43da973b9c0c20bdbd81203",
|
||||
"reference": "69a40779d8fc43e3f43da973b9c0c20bdbd81203",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -892,20 +892,20 @@
|
||||
],
|
||||
"description": "The Illuminate Contracts package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"time": "2020-03-31T14:24:32+00:00"
|
||||
"time": "2020-04-09T15:01:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/events",
|
||||
"version": "v7.4.0",
|
||||
"version": "v7.6.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/events.git",
|
||||
"reference": "442fd9cdbacc0732eea4018bc1f0df7e4004b8e8"
|
||||
"reference": "59f6074ff6b14b475c7c97021dcbcd2e2bce2ebd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/events/zipball/442fd9cdbacc0732eea4018bc1f0df7e4004b8e8",
|
||||
"reference": "442fd9cdbacc0732eea4018bc1f0df7e4004b8e8",
|
||||
"url": "https://api.github.com/repos/illuminate/events/zipball/59f6074ff6b14b475c7c97021dcbcd2e2bce2ebd",
|
||||
"reference": "59f6074ff6b14b475c7c97021dcbcd2e2bce2ebd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -937,11 +937,11 @@
|
||||
],
|
||||
"description": "The Illuminate Events package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"time": "2020-02-11T22:47:28+00:00"
|
||||
"time": "2020-04-14T13:14:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/filesystem",
|
||||
"version": "v7.4.0",
|
||||
"version": "v7.6.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/filesystem.git",
|
||||
@@ -993,17 +993,120 @@
|
||||
"time": "2020-03-26T19:53:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/support",
|
||||
"version": "v7.4.0",
|
||||
"name": "illuminate/http",
|
||||
"version": "v7.6.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/support.git",
|
||||
"reference": "6b5a135637bf901e5dd9c0e3d906a97d550d4cee"
|
||||
"url": "https://github.com/illuminate/http.git",
|
||||
"reference": "c11e7175b7b751ce8ae5dfac7fbe46d47b6c2f39"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/support/zipball/6b5a135637bf901e5dd9c0e3d906a97d550d4cee",
|
||||
"reference": "6b5a135637bf901e5dd9c0e3d906a97d550d4cee",
|
||||
"url": "https://api.github.com/repos/illuminate/http/zipball/c11e7175b7b751ce8ae5dfac7fbe46d47b6c2f39",
|
||||
"reference": "c11e7175b7b751ce8ae5dfac7fbe46d47b6c2f39",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"illuminate/session": "^7.0",
|
||||
"illuminate/support": "^7.0",
|
||||
"php": "^7.2.5",
|
||||
"symfony/http-foundation": "^5.0",
|
||||
"symfony/http-kernel": "^5.0",
|
||||
"symfony/mime": "^5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().",
|
||||
"guzzlehttp/guzzle": "Required to use the HTTP Client (^6.3.1|^7.0)."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Http\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Http package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"time": "2020-04-15T18:37:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/session",
|
||||
"version": "v7.6.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/session.git",
|
||||
"reference": "4285f5208e0a59286763c591281d5d6e66e66b84"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/session/zipball/4285f5208e0a59286763c591281d5d6e66e66b84",
|
||||
"reference": "4285f5208e0a59286763c591281d5d6e66e66b84",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"illuminate/contracts": "^7.0",
|
||||
"illuminate/filesystem": "^7.0",
|
||||
"illuminate/support": "^7.0",
|
||||
"php": "^7.2.5",
|
||||
"symfony/finder": "^5.0",
|
||||
"symfony/http-foundation": "^5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"illuminate/console": "Required to use the session:table command (^7.0)."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Session\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Session package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"time": "2020-01-07T13:49:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/support",
|
||||
"version": "v7.6.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/support.git",
|
||||
"reference": "b6f64a42377f86b293960e0b7f6920ae59e578d2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/support/zipball/b6f64a42377f86b293960e0b7f6920ae59e578d2",
|
||||
"reference": "b6f64a42377f86b293960e0b7f6920ae59e578d2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1052,20 +1155,20 @@
|
||||
],
|
||||
"description": "The Illuminate Support package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"time": "2020-03-30T13:52:20+00:00"
|
||||
"time": "2020-04-15T19:48:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/testing",
|
||||
"version": "v7.4.0",
|
||||
"version": "v7.6.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/testing.git",
|
||||
"reference": "55fde302562febe3461c5732e6972b1626bfabcc"
|
||||
"reference": "670d48ce1afd008d6e48b2a77c29691ffd4581a3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/testing/zipball/55fde302562febe3461c5732e6972b1626bfabcc",
|
||||
"reference": "55fde302562febe3461c5732e6972b1626bfabcc",
|
||||
"url": "https://api.github.com/repos/illuminate/testing/zipball/670d48ce1afd008d6e48b2a77c29691ffd4581a3",
|
||||
"reference": "670d48ce1afd008d6e48b2a77c29691ffd4581a3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1103,97 +1206,7 @@
|
||||
],
|
||||
"description": "The Illuminate Testing package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"time": "2020-03-30T13:58:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jakub-onderka/php-console-color",
|
||||
"version": "v0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/JakubOnderka/PHP-Console-Color.git",
|
||||
"reference": "d5deaecff52a0d61ccb613bb3804088da0307191"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Color/zipball/d5deaecff52a0d61ccb613bb3804088da0307191",
|
||||
"reference": "d5deaecff52a0d61ccb613bb3804088da0307191",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"jakub-onderka/php-code-style": "1.0",
|
||||
"jakub-onderka/php-parallel-lint": "1.0",
|
||||
"jakub-onderka/php-var-dump-check": "0.*",
|
||||
"phpunit/phpunit": "~4.3",
|
||||
"squizlabs/php_codesniffer": "1.*"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"JakubOnderka\\PhpConsoleColor\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-2-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jakub Onderka",
|
||||
"email": "jakub.onderka@gmail.com"
|
||||
}
|
||||
],
|
||||
"abandoned": "php-parallel-lint/php-console-color",
|
||||
"time": "2018-09-29T17:23:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jakub-onderka/php-console-highlighter",
|
||||
"version": "v0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/JakubOnderka/PHP-Console-Highlighter.git",
|
||||
"reference": "9f7a229a69d52506914b4bc61bfdb199d90c5547"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Highlighter/zipball/9f7a229a69d52506914b4bc61bfdb199d90c5547",
|
||||
"reference": "9f7a229a69d52506914b4bc61bfdb199d90c5547",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-tokenizer": "*",
|
||||
"jakub-onderka/php-console-color": "~0.2",
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"jakub-onderka/php-code-style": "~1.0",
|
||||
"jakub-onderka/php-parallel-lint": "~1.0",
|
||||
"jakub-onderka/php-var-dump-check": "~0.1",
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"squizlabs/php_codesniffer": "~1.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"JakubOnderka\\PhpConsoleHighlighter\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jakub Onderka",
|
||||
"email": "acci@acci.cz",
|
||||
"homepage": "http://www.acci.cz/"
|
||||
}
|
||||
],
|
||||
"description": "Highlight PHP code in terminal",
|
||||
"abandoned": "php-parallel-lint/php-console-highlighter",
|
||||
"time": "2018-09-29T18:48:56+00:00"
|
||||
"time": "2020-04-14T14:05:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jolicode/jolinotif",
|
||||
@@ -1642,16 +1655,16 @@
|
||||
},
|
||||
{
|
||||
"name": "laravel-zero/foundation",
|
||||
"version": "v7.4.0",
|
||||
"version": "v7.6.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel-zero/foundation.git",
|
||||
"reference": "99b7b78ceb78252249478e1cde228e5e48e3fd64"
|
||||
"reference": "61438f6d9220d2e20f8610ccbe894507d89f8f1a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel-zero/foundation/zipball/99b7b78ceb78252249478e1cde228e5e48e3fd64",
|
||||
"reference": "99b7b78ceb78252249478e1cde228e5e48e3fd64",
|
||||
"url": "https://api.github.com/repos/laravel-zero/foundation/zipball/61438f6d9220d2e20f8610ccbe894507d89f8f1a",
|
||||
"reference": "61438f6d9220d2e20f8610ccbe894507d89f8f1a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1680,7 +1693,7 @@
|
||||
"framework",
|
||||
"laravel"
|
||||
],
|
||||
"time": "2020-04-01T08:40:16+00:00"
|
||||
"time": "2020-04-14T16:39:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel-zero/framework",
|
||||
@@ -1852,6 +1865,56 @@
|
||||
],
|
||||
"time": "2020-03-17T18:58:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "namshi/cuzzle",
|
||||
"version": "2.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/namshi/cuzzle.git",
|
||||
"reference": "89849bb9c729a3d8aabf94c0b66e77c7df38abda"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/namshi/cuzzle/zipball/89849bb9c729a3d8aabf94c0b66e77c7df38abda",
|
||||
"reference": "89849bb9c729a3d8aabf94c0b66e77c7df38abda",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"guzzlehttp/guzzle": "^6.0",
|
||||
"php": ">=5.5.0",
|
||||
"psr/log": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.2.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Namshi\\Cuzzle\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nikita Nefedov",
|
||||
"email": "inefedor@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "cirpo",
|
||||
"email": "alessandro.cinelli@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Get the cURL shell command from a Guzzle request",
|
||||
"time": "2016-11-23T08:01:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "2.32.2",
|
||||
@@ -1925,28 +1988,28 @@
|
||||
},
|
||||
{
|
||||
"name": "nunomaduro/collision",
|
||||
"version": "v4.1.3",
|
||||
"version": "v4.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nunomaduro/collision.git",
|
||||
"reference": "a430bce33d1ad07f756ea6cae9afce9ef8670b42"
|
||||
"reference": "d50490417eded97be300a92cd7df7badc37a9018"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nunomaduro/collision/zipball/a430bce33d1ad07f756ea6cae9afce9ef8670b42",
|
||||
"reference": "a430bce33d1ad07f756ea6cae9afce9ef8670b42",
|
||||
"url": "https://api.github.com/repos/nunomaduro/collision/zipball/d50490417eded97be300a92cd7df7badc37a9018",
|
||||
"reference": "d50490417eded97be300a92cd7df7badc37a9018",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"facade/ignition-contracts": "^1.0",
|
||||
"filp/whoops": "^2.4",
|
||||
"jakub-onderka/php-console-highlighter": "^0.4",
|
||||
"php": "^7.2.5",
|
||||
"symfony/console": "^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"facade/ignition": "^2.0",
|
||||
"fideloper/proxy": "^4.2",
|
||||
"friendsofphp/php-cs-fixer": "^2.16",
|
||||
"fruitcake/laravel-cors": "^1.0",
|
||||
"laravel/framework": "^7.0",
|
||||
"laravel/tinker": "^2.0",
|
||||
@@ -1991,7 +2054,7 @@
|
||||
"php",
|
||||
"symfony"
|
||||
],
|
||||
"time": "2020-03-07T12:46:00+00:00"
|
||||
"time": "2020-04-04T19:56:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nunomaduro/laravel-console-summary",
|
||||
@@ -2321,6 +2384,52 @@
|
||||
],
|
||||
"time": "2017-02-14T16:28:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/event-dispatcher",
|
||||
"version": "1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/event-dispatcher.git",
|
||||
"reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0",
|
||||
"reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\EventDispatcher\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Standard interfaces for event handling.",
|
||||
"keywords": [
|
||||
"events",
|
||||
"psr",
|
||||
"psr-14"
|
||||
],
|
||||
"time": "2019-01-08T18:20:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-message",
|
||||
"version": "1.0.1",
|
||||
@@ -3301,6 +3410,134 @@
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2020-03-30T14:14:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v5.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
"reference": "24f40d95385774ed5c71dbf014edd047e2f2f3dc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/24f40d95385774ed5c71dbf014edd047e2f2f3dc",
|
||||
"reference": "24f40d95385774ed5c71dbf014edd047e2f2f3dc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2.5",
|
||||
"symfony/event-dispatcher-contracts": "^2"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/dependency-injection": "<4.4"
|
||||
},
|
||||
"provide": {
|
||||
"psr/event-dispatcher-implementation": "1.0",
|
||||
"symfony/event-dispatcher-implementation": "2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"psr/log": "~1.0",
|
||||
"symfony/config": "^4.4|^5.0",
|
||||
"symfony/dependency-injection": "^4.4|^5.0",
|
||||
"symfony/expression-language": "^4.4|^5.0",
|
||||
"symfony/http-foundation": "^4.4|^5.0",
|
||||
"symfony/service-contracts": "^1.1|^2",
|
||||
"symfony/stopwatch": "^4.4|^5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/dependency-injection": "",
|
||||
"symfony/http-kernel": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\EventDispatcher\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony EventDispatcher Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2020-03-27T16:56:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher-contracts",
|
||||
"version": "v2.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher-contracts.git",
|
||||
"reference": "af23c2584d4577d54661c434446fb8fbed6025dd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/af23c2584d4577d54661c434446fb8fbed6025dd",
|
||||
"reference": "af23c2584d4577d54661c434446fb8fbed6025dd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2.5",
|
||||
"psr/event-dispatcher": "^1"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/event-dispatcher-implementation": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Contracts\\EventDispatcher\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Generic abstractions related to dispatching event",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"abstractions",
|
||||
"contracts",
|
||||
"decoupling",
|
||||
"interfaces",
|
||||
"interoperability",
|
||||
"standards"
|
||||
],
|
||||
"time": "2019-11-18T17:27:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v5.0.7",
|
||||
@@ -3405,6 +3642,102 @@
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2020-03-30T14:14:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-kernel",
|
||||
"version": "v5.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-kernel.git",
|
||||
"reference": "ad574c55d451127cab1c45b4ac51bf283e340cf0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/ad574c55d451127cab1c45b4ac51bf283e340cf0",
|
||||
"reference": "ad574c55d451127cab1c45b4ac51bf283e340cf0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2.5",
|
||||
"psr/log": "~1.0",
|
||||
"symfony/error-handler": "^4.4|^5.0",
|
||||
"symfony/event-dispatcher": "^5.0",
|
||||
"symfony/http-foundation": "^4.4|^5.0",
|
||||
"symfony/polyfill-ctype": "^1.8",
|
||||
"symfony/polyfill-php73": "^1.9"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/browser-kit": "<4.4",
|
||||
"symfony/cache": "<5.0",
|
||||
"symfony/config": "<5.0",
|
||||
"symfony/dependency-injection": "<4.4",
|
||||
"symfony/doctrine-bridge": "<5.0",
|
||||
"symfony/form": "<5.0",
|
||||
"symfony/http-client": "<5.0",
|
||||
"symfony/mailer": "<5.0",
|
||||
"symfony/messenger": "<5.0",
|
||||
"symfony/translation": "<5.0",
|
||||
"symfony/twig-bridge": "<5.0",
|
||||
"symfony/validator": "<5.0",
|
||||
"twig/twig": "<2.4"
|
||||
},
|
||||
"provide": {
|
||||
"psr/log-implementation": "1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"psr/cache": "~1.0",
|
||||
"symfony/browser-kit": "^4.4|^5.0",
|
||||
"symfony/config": "^5.0",
|
||||
"symfony/console": "^4.4|^5.0",
|
||||
"symfony/css-selector": "^4.4|^5.0",
|
||||
"symfony/dependency-injection": "^4.4|^5.0",
|
||||
"symfony/dom-crawler": "^4.4|^5.0",
|
||||
"symfony/expression-language": "^4.4|^5.0",
|
||||
"symfony/finder": "^4.4|^5.0",
|
||||
"symfony/process": "^4.4|^5.0",
|
||||
"symfony/routing": "^4.4|^5.0",
|
||||
"symfony/stopwatch": "^4.4|^5.0",
|
||||
"symfony/translation": "^4.4|^5.0",
|
||||
"symfony/translation-contracts": "^1.1|^2",
|
||||
"twig/twig": "^2.4|^3.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/browser-kit": "",
|
||||
"symfony/config": "",
|
||||
"symfony/console": "",
|
||||
"symfony/dependency-injection": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\HttpKernel\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony HttpKernel Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2020-03-30T15:04:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/mime",
|
||||
"version": "v5.0.7",
|
||||
@@ -3808,6 +4141,70 @@
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2020-03-27T16:56:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/psr-http-message-bridge",
|
||||
"version": "v2.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/psr-http-message-bridge.git",
|
||||
"reference": "ce709cd9c90872c08c2427b45739d5f3c781ab4f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/ce709cd9c90872c08c2427b45739d5f3c781ab4f",
|
||||
"reference": "ce709cd9c90872c08c2427b45739d5f3c781ab4f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1",
|
||||
"psr/http-message": "^1.0",
|
||||
"symfony/http-foundation": "^4.4 || ^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"nyholm/psr7": "^1.1",
|
||||
"symfony/phpunit-bridge": "^4.4 || ^5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"nyholm/psr7": "For a super lightweight PSR-7/17 implementation"
|
||||
},
|
||||
"type": "symfony-bridge",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Bridge\\PsrHttpMessage\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "PSR HTTP message bridge",
|
||||
"homepage": "http://symfony.com",
|
||||
"keywords": [
|
||||
"http",
|
||||
"http-message",
|
||||
"psr-17",
|
||||
"psr-7"
|
||||
],
|
||||
"time": "2020-01-02T08:07:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/routing",
|
||||
"version": "v5.0.7",
|
||||
@@ -4153,16 +4550,16 @@
|
||||
},
|
||||
{
|
||||
"name": "vlucas/phpdotenv",
|
||||
"version": "v4.1.3",
|
||||
"version": "v4.1.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vlucas/phpdotenv.git",
|
||||
"reference": "88f7acc95150bca002a498899f8b52f318e444c2"
|
||||
"reference": "feb6dad5ae24b1380827aee1629b730080fde500"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/88f7acc95150bca002a498899f8b52f318e444c2",
|
||||
"reference": "88f7acc95150bca002a498899f8b52f318e444c2",
|
||||
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/feb6dad5ae24b1380827aee1629b730080fde500",
|
||||
"reference": "feb6dad5ae24b1380827aee1629b730080fde500",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4213,7 +4610,7 @@
|
||||
"env",
|
||||
"environment"
|
||||
],
|
||||
"time": "2020-03-27T23:37:15+00:00"
|
||||
"time": "2020-04-12T15:20:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "voku/portable-ascii",
|
||||
|
||||
@@ -13,7 +13,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'name' => 'Phunnel',
|
||||
'name' => 'Expose',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
||||
@@ -2,9 +2,82 @@
|
||||
<head>
|
||||
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tailwindcss/ui@latest/dist/tailwind-ui.min.css">
|
||||
<script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js?skin=sunburst"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script>
|
||||
<script>
|
||||
!function(a,b){"function"==typeof define&&define.amd?define([],b):"undefined"!=typeof module&&module.exports?module.exports=b():a.ReconnectingWebSocket=b()}(this,function(){function a(b,c,d){function l(a,b){var c=document.createEvent("CustomEvent");return c.initCustomEvent(a,!1,!1,b),c}var e={debug:!1,automaticOpen:!0,reconnectInterval:1e3,maxReconnectInterval:3e4,reconnectDecay:1.5,timeoutInterval:2e3};d||(d={});for(var f in e)this[f]="undefined"!=typeof d[f]?d[f]:e[f];this.url=b,this.reconnectAttempts=0,this.readyState=WebSocket.CONNECTING,this.protocol=null;var h,g=this,i=!1,j=!1,k=document.createElement("div");k.addEventListener("open",function(a){g.onopen(a)}),k.addEventListener("close",function(a){g.onclose(a)}),k.addEventListener("connecting",function(a){g.onconnecting(a)}),k.addEventListener("message",function(a){g.onmessage(a)}),k.addEventListener("error",function(a){g.onerror(a)}),this.addEventListener=k.addEventListener.bind(k),this.removeEventListener=k.removeEventListener.bind(k),this.dispatchEvent=k.dispatchEvent.bind(k),this.open=function(b){h=new WebSocket(g.url,c||[]),b||k.dispatchEvent(l("connecting")),(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","attempt-connect",g.url);var d=h,e=setTimeout(function(){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","connection-timeout",g.url),j=!0,d.close(),j=!1},g.timeoutInterval);h.onopen=function(){clearTimeout(e),(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onopen",g.url),g.protocol=h.protocol,g.readyState=WebSocket.OPEN,g.reconnectAttempts=0;var d=l("open");d.isReconnect=b,b=!1,k.dispatchEvent(d)},h.onclose=function(c){if(clearTimeout(e),h=null,i)g.readyState=WebSocket.CLOSED,k.dispatchEvent(l("close"));else{g.readyState=WebSocket.CONNECTING;var d=l("connecting");d.code=c.code,d.reason=c.reason,d.wasClean=c.wasClean,k.dispatchEvent(d),b||j||((g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onclose",g.url),k.dispatchEvent(l("close")));var e=g.reconnectInterval*Math.pow(g.reconnectDecay,g.reconnectAttempts);setTimeout(function(){g.reconnectAttempts++,g.open(!0)},e>g.maxReconnectInterval?g.maxReconnectInterval:e)}},h.onmessage=function(b){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onmessage",g.url,b.data);var c=l("message");c.data=b.data,k.dispatchEvent(c)},h.onerror=function(b){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onerror",g.url,b),k.dispatchEvent(l("error"))}},1==this.automaticOpen&&this.open(!1),this.send=function(b){if(h)return(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","send",g.url,b),h.send(b);throw"INVALID_STATE_ERR : Pausing to reconnect websocket"},this.close=function(a,b){"undefined"==typeof a&&(a=1e3),i=!0,h&&h.close(a,b)},this.refresh=function(){h&&h.close()}}return a.prototype.onopen=function(){},a.prototype.onclose=function(){},a.prototype.onconnecting=function(){},a.prototype.onmessage=function(){},a.prototype.onerror=function(){},a.debugAll=!1,a.CONNECTING=WebSocket.CONNECTING,a.OPEN=WebSocket.OPEN,a.CLOSING=WebSocket.CLOSING,a.CLOSED=WebSocket.CLOSED,a});
|
||||
!function (a, b) {
|
||||
"function" == typeof define && define.amd ? define([], b) : "undefined" != typeof module && module.exports ? module.exports = b() : a.ReconnectingWebSocket = b()
|
||||
}(this, function () {
|
||||
function a(b, c, d) {
|
||||
function l(a, b) {
|
||||
var c = document.createEvent("CustomEvent");
|
||||
return c.initCustomEvent(a, !1, !1, b), c
|
||||
}
|
||||
|
||||
var e = {
|
||||
debug: !1,
|
||||
automaticOpen: !0,
|
||||
reconnectInterval: 1e3,
|
||||
maxReconnectInterval: 3e4,
|
||||
reconnectDecay: 1.5,
|
||||
timeoutInterval: 2e3
|
||||
};
|
||||
d || (d = {});
|
||||
for (var f in e) this[f] = "undefined" != typeof d[f] ? d[f] : e[f];
|
||||
this.url = b, this.reconnectAttempts = 0, this.readyState = WebSocket.CONNECTING, this.protocol = null;
|
||||
var h, g = this, i = !1, j = !1, k = document.createElement("div");
|
||||
k.addEventListener("open", function (a) {
|
||||
g.onopen(a)
|
||||
}), k.addEventListener("close", function (a) {
|
||||
g.onclose(a)
|
||||
}), k.addEventListener("connecting", function (a) {
|
||||
g.onconnecting(a)
|
||||
}), k.addEventListener("message", function (a) {
|
||||
g.onmessage(a)
|
||||
}), k.addEventListener("error", function (a) {
|
||||
g.onerror(a)
|
||||
}), this.addEventListener = k.addEventListener.bind(k), this.removeEventListener = k.removeEventListener.bind(k), this.dispatchEvent = k.dispatchEvent.bind(k), this.open = function (b) {
|
||||
h = new WebSocket(g.url, c || []), b || k.dispatchEvent(l("connecting")), (g.debug || a.debugAll) && console.debug("ReconnectingWebSocket", "attempt-connect", g.url);
|
||||
var d = h, e = setTimeout(function () {
|
||||
(g.debug || a.debugAll) && console.debug("ReconnectingWebSocket", "connection-timeout", g.url), j = !0, d.close(), j = !1
|
||||
}, g.timeoutInterval);
|
||||
h.onopen = function () {
|
||||
clearTimeout(e), (g.debug || a.debugAll) && console.debug("ReconnectingWebSocket", "onopen", g.url), g.protocol = h.protocol, g.readyState = WebSocket.OPEN, g.reconnectAttempts = 0;
|
||||
var d = l("open");
|
||||
d.isReconnect = b, b = !1, k.dispatchEvent(d)
|
||||
}, h.onclose = function (c) {
|
||||
if (clearTimeout(e), h = null, i) g.readyState = WebSocket.CLOSED, k.dispatchEvent(l("close")); else {
|
||||
g.readyState = WebSocket.CONNECTING;
|
||||
var d = l("connecting");
|
||||
d.code = c.code, d.reason = c.reason, d.wasClean = c.wasClean, k.dispatchEvent(d), b || j || ((g.debug || a.debugAll) && console.debug("ReconnectingWebSocket", "onclose", g.url), k.dispatchEvent(l("close")));
|
||||
var e = g.reconnectInterval * Math.pow(g.reconnectDecay, g.reconnectAttempts);
|
||||
setTimeout(function () {
|
||||
g.reconnectAttempts++, g.open(!0)
|
||||
}, e > g.maxReconnectInterval ? g.maxReconnectInterval : e)
|
||||
}
|
||||
}, h.onmessage = function (b) {
|
||||
(g.debug || a.debugAll) && console.debug("ReconnectingWebSocket", "onmessage", g.url, b.data);
|
||||
var c = l("message");
|
||||
c.data = b.data, k.dispatchEvent(c)
|
||||
}, h.onerror = function (b) {
|
||||
(g.debug || a.debugAll) && console.debug("ReconnectingWebSocket", "onerror", g.url, b), k.dispatchEvent(l("error"))
|
||||
}
|
||||
}, 1 == this.automaticOpen && this.open(!1), this.send = function (b) {
|
||||
if (h) return (g.debug || a.debugAll) && console.debug("ReconnectingWebSocket", "send", g.url, b), h.send(b);
|
||||
throw"INVALID_STATE_ERR : Pausing to reconnect websocket"
|
||||
}, this.close = function (a, b) {
|
||||
"undefined" == typeof a && (a = 1e3), i = !0, h && h.close(a, b)
|
||||
}, this.refresh = function () {
|
||||
h && h.close()
|
||||
}
|
||||
}
|
||||
|
||||
return a.prototype.onopen = function () {
|
||||
}, a.prototype.onclose = function () {
|
||||
}, a.prototype.onconnecting = function () {
|
||||
}, a.prototype.onmessage = function () {
|
||||
}, a.prototype.onerror = function () {
|
||||
}, a.debugAll = !1, a.CONNECTING = WebSocket.CONNECTING, a.OPEN = WebSocket.OPEN, a.CLOSING = WebSocket.CLOSING, a.CLOSED = WebSocket.CLOSED, a
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
.even\:bg-gray-50:nth-child(even) {
|
||||
@@ -13,10 +86,29 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app" class="p-5 flex flex-row">
|
||||
<div id="app" class="">
|
||||
<div class="relative bg-indigo-600" style="marign-left: -1px">
|
||||
<div class="max-w-screen-xl mx-auto py-3 px-3 sm:px-6 lg:px-8">
|
||||
<div class="pr-16 sm:text-center sm:px-16">
|
||||
<p class="font-medium text-white flex justify-center">
|
||||
<span class="inline-block">Waiting for requests on: <a class="underline" target="_blank"
|
||||
href="%subdomains%">%subdomains%</a></span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-5 flex flex-row">
|
||||
<div class="w-1/3 flex flex-col mr-5">
|
||||
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
||||
<div class="align-middle inline-block min-w-full shadow overflow-hidden sm:rounded-lg border-b border-gray-200">
|
||||
<span class="inline-flex rounded-md shadow-sm mb-4">
|
||||
<button @click.prevent="clearLogs"
|
||||
type="button"
|
||||
class="inline-flex items-center px-2.5 py-1.5 border border-gray-300 text-xs leading-4 font-medium rounded text-gray-700 bg-white hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:text-gray-800 active:bg-gray-50 transition ease-in-out duration-150">
|
||||
Clear
|
||||
</button>
|
||||
</span>
|
||||
<div
|
||||
class="align-middle inline-block min-w-full shadow overflow-hidden sm:rounded-lg border-b border-gray-200">
|
||||
<table class="min-w-full">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -32,30 +124,30 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white">
|
||||
<tr v-for="log in logs"
|
||||
:class="{'bg-gray-100': currentLog === log}"
|
||||
@click="setLog(log)">
|
||||
<td class="cursor.pointer px-6 py-4 whitespace-no-wrap border-b border-gray-200 text-sm leading-5 font-medium text-gray-900">
|
||||
<p>
|
||||
{{ log.request.method }}
|
||||
{{ log.request.uri }}
|
||||
</p>
|
||||
<span class="text-xs">{{ log.subdomain }}</span>
|
||||
</td>
|
||||
<td class="cursor.pointer px-6 py-4 whitespace-no-wrap border-b border-gray-200 text-sm leading-5 text-gray-500">
|
||||
<div v-if="log.response">
|
||||
{{ log.response.status }} - {{ log.response.reason }}
|
||||
</div>
|
||||
<div v-else>
|
||||
...
|
||||
</div>
|
||||
</td>
|
||||
<td class="cursor.pointer px-6 py-4 whitespace-no-wrap border-b border-gray-200 text-sm leading-5 text-gray-500">
|
||||
<div v-if="log.response">
|
||||
{{ log.duration }}ms
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-for="log in logs"
|
||||
:class="{'bg-gray-100': currentLog === log}"
|
||||
@click="setLog(log)">
|
||||
<td class="cursor.pointer px-6 py-4 whitespace-no-wrap border-b border-gray-200 text-sm leading-5 font-medium text-gray-900">
|
||||
<p>
|
||||
{{ log.request.method }}
|
||||
{{ log.request.uri }}
|
||||
</p>
|
||||
<span class="text-xs">{{ log.subdomain }}</span>
|
||||
</td>
|
||||
<td class="cursor.pointer px-6 py-4 whitespace-no-wrap border-b border-gray-200 text-sm leading-5 text-gray-500">
|
||||
<div v-if="log.response">
|
||||
{{ log.response.status }} - {{ log.response.reason }}
|
||||
</div>
|
||||
<div v-else>
|
||||
...
|
||||
</div>
|
||||
</td>
|
||||
<td class="cursor.pointer px-6 py-4 whitespace-no-wrap border-b border-gray-200 text-sm leading-5 text-gray-500">
|
||||
<div v-if="log.response">
|
||||
{{ log.duration }}ms
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -68,11 +160,20 @@
|
||||
{{ currentLog.request.method }} {{ currentLog.request.uri }}
|
||||
<div class="flex-grow"></div>
|
||||
<span class="inline-flex rounded-md shadow-sm">
|
||||
<button @click.prevent="replay(currentLog)"
|
||||
type="button" class="inline-flex items-center px-2.5 py-1.5 border border-gray-300 text-xs leading-4 font-medium rounded text-gray-700 bg-white hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:text-gray-800 active:bg-gray-50 transition ease-in-out duration-150">
|
||||
Replay
|
||||
</button>
|
||||
</span>
|
||||
<button @click.prevent="replay(currentLog)"
|
||||
type="button"
|
||||
class="inline-flex items-center px-2.5 py-1.5 border border-gray-300 text-xs leading-4 font-medium rounded text-gray-700 bg-white hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:text-gray-800 active:bg-gray-50 transition ease-in-out duration-150">
|
||||
Replay
|
||||
</button>
|
||||
</span>
|
||||
<span class="inline-flex rounded-md shadow-sm ml-4">
|
||||
<button
|
||||
:data-clipboard-text="currentLog.request.curl"
|
||||
type="button"
|
||||
class="clipboard inline-flex items-center px-2.5 py-1.5 border border-gray-300 text-xs leading-4 font-medium rounded text-gray-700 bg-white hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:text-gray-800 active:bg-gray-50 transition ease-in-out duration-150">
|
||||
Copy as curl
|
||||
</button>
|
||||
</span>
|
||||
</h3>
|
||||
<p class="mt-1 max-w-2xl text-sm leading-5 text-gray-500">
|
||||
Status code: {{ currentLog.response?.status}}
|
||||
@@ -135,7 +236,8 @@
|
||||
{{ parameter.name }}
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
<span v-if="parameter.is_file">File: {{ parameter.filename }} ({{ parameter.mime_type }})</span>
|
||||
<span
|
||||
v-if="parameter.is_file">File: {{ parameter.filename }} ({{ parameter.mime_type }})</span>
|
||||
<span v-else>{{ parameter.value }}</span>
|
||||
</dd>
|
||||
</div>
|
||||
@@ -177,14 +279,66 @@
|
||||
{{ value }}
|
||||
</dd>
|
||||
</div>
|
||||
<div v-if="currentLog.request.additional_data.length !== 0">
|
||||
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
||||
<dt class="text-sm leading-5 font-medium text-gray-900">
|
||||
Debug
|
||||
</dt>
|
||||
</div>
|
||||
<div v-for="(value, key) in currentLog.request.additional_data"
|
||||
:key="'debug'+key"
|
||||
class="even:bg-gray-50 odd:bg-gray-50 px-4 py-3 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
||||
<dt class="text-sm leading-5 font-medium text-gray-500">
|
||||
{{ key }}
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
<div v-html="value">
|
||||
</dd>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<pre class="p-6 prettyprint">{{ currentLog.response.body }}</pre>
|
||||
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
|
||||
<dt class="text-sm leading-5 font-medium text-gray-900">
|
||||
Response
|
||||
</dt>
|
||||
<div>
|
||||
<div class="sm:hidden">
|
||||
<select class="form-select block w-full">
|
||||
<option>My Account</option>
|
||||
<option>Company</option>
|
||||
<option selected>Team Members</option>
|
||||
<option>Billing</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="hidden sm:block">
|
||||
<nav class="flex">
|
||||
<a href="#"
|
||||
@click.prevent="setActiveTab('raw')"
|
||||
:class="{'outline-none text-gray-700 bg-gray-100': activeTab === 'raw'}"
|
||||
class="px-3 py-2 font-medium text-sm leading-5 rounded-md text-gray-500 hover:text-gray-700">
|
||||
Raw
|
||||
</a>
|
||||
<a href="#"
|
||||
@click.prevent="setActiveTab('preview')"
|
||||
:class="{'outline-none text-gray-700 bg-gray-100': activeTab === 'preview'}"
|
||||
class="ml-4 px-3 py-2 font-medium text-sm leading-5 rounded-md text-gray-500 hover:text-gray-700 focus:outline-none focus:text-gray-700 focus:bg-gray-100">
|
||||
Preview
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="activeTab === 'raw'">
|
||||
<pre class="p-6 text-sm">{{ currentLog.response.body }}</pre>
|
||||
</div>
|
||||
<div v-if="activeTab === 'preview'">
|
||||
<iframe :srcdoc="currentLog.response.body" style="height: 500px;" class="w-full h-full"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
new Vue({
|
||||
@@ -193,35 +347,38 @@
|
||||
data: {
|
||||
currentLog: null,
|
||||
view: 'request',
|
||||
activeTab: 'raw',
|
||||
logs: [],
|
||||
},
|
||||
|
||||
methods: {
|
||||
setLog: function(log) {
|
||||
setActiveTab: function(tab) {
|
||||
this.activeTab = tab;
|
||||
},
|
||||
clearLogs: function() {
|
||||
fetch('/logs/clear');
|
||||
},
|
||||
setLog: function (log) {
|
||||
this.currentLog = log;
|
||||
|
||||
this.$nextTick(function(){
|
||||
PR.prettyPrint();
|
||||
this.$nextTick(function () {
|
||||
let clipboard = new ClipboardJS('.clipboard');
|
||||
});
|
||||
},
|
||||
setView: function(view) {
|
||||
setView: function (view) {
|
||||
this.view = view;
|
||||
|
||||
this.$nextTick(function(){
|
||||
PR.prettyPrint();
|
||||
});
|
||||
},
|
||||
replay: function(log) {
|
||||
fetch('/replay/'+log.id);
|
||||
replay: function (log) {
|
||||
fetch('/replay/' + log.id);
|
||||
},
|
||||
connect: function() {
|
||||
connect: function () {
|
||||
let conn = new ReconnectingWebSocket(`ws://${window.location.hostname}:${window.location.port}/socket`);
|
||||
|
||||
conn.onmessage = (e) => {
|
||||
this.logs = JSON.parse(e.data);
|
||||
};
|
||||
},
|
||||
loadLogs: function(log) {
|
||||
loadLogs: function (log) {
|
||||
fetch('/logs')
|
||||
.then((response) => {
|
||||
return response.json();
|
||||
@@ -232,7 +389,7 @@
|
||||
},
|
||||
},
|
||||
|
||||
mounted: function() {
|
||||
mounted: function () {
|
||||
this.connect();
|
||||
|
||||
this.loadLogs();
|
||||
|
||||
Reference in New Issue
Block a user