Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
100.00% |
11 / 11 |
|
100.00% |
2 / 2 |
CRAP | |
100.00% |
1 / 1 |
| PlaygroundController | |
100.00% |
11 / 11 |
|
100.00% |
2 / 2 |
2 | |
100.00% |
1 / 1 |
| __construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| __invoke | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
1 | |||
| 1 | <?php |
| 2 | namespace Apie\TypescriptClientBuilder\Controllers; |
| 3 | |
| 4 | use Nyholm\Psr7\Response; |
| 5 | use Psr\Http\Message\ResponseInterface; |
| 6 | |
| 7 | /** |
| 8 | * Serves a test page that runs the generated TypeScript client in the BrowserPlayground. |
| 9 | */ |
| 10 | class PlaygroundController |
| 11 | { |
| 12 | public function __construct(private readonly string $jsBasePath = '/js/contents') |
| 13 | { |
| 14 | } |
| 15 | |
| 16 | public function __invoke(): ResponseInterface |
| 17 | { |
| 18 | $base = htmlspecialchars($this->jsBasePath, ENT_QUOTES); |
| 19 | $html = <<<HTML |
| 20 | <!DOCTYPE html> |
| 21 | <html lang="en"> |
| 22 | <head> |
| 23 | <meta charset="utf-8"> |
| 24 | <title>Apie Test Playground</title> |
| 25 | <meta name="viewport" content="width=device-width, initial-scale=1"> |
| 26 | <script type="importmap"> |
| 27 | { |
| 28 | "imports": { |
| 29 | "{$base}/es6/index": "{$base}/es6/index.js", |
| 30 | "{$base}/es6/build-script": "{$base}/es6/build-script.js", |
| 31 | "{$base}/es6/transport-layer": "{$base}/es6/transport-layer.js" |
| 32 | } |
| 33 | } |
| 34 | </script> |
| 35 | <style> |
| 36 | body { font-family: system-ui, sans-serif; margin: 0; background: #f4f5f7; color: #1d2433; } |
| 37 | #playground { max-width: 1200px; margin: 0 auto; padding: 1rem; } |
| 38 | header { display: flex; justify-content: space-between; align-items: center; } |
| 39 | .layout { display: grid; grid-template-columns: 260px 1fr; gap: 1rem; } |
| 40 | .panel { background: #fff; border: 1px solid #d9dce3; border-radius: 6px; padding: 1rem; margin-bottom: 1rem; } |
| 41 | .panel-head { display: flex; justify-content: space-between; align-items: center; } |
| 42 | .tabs, .entity-list, .flags, .test-buttons { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: .5rem; } |
| 43 | .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: .75rem; } |
| 44 | .grid label { display: flex; flex-direction: column; font-size: .85rem; gap: .2rem; } |
| 45 | button { padding: .35rem .8rem; border: 1px solid #b8bdc9; border-radius: 4px; background: #fff; cursor: pointer; } |
| 46 | button.active, button.primary { background: #2b5fd9; border-color: #2b5fd9; color: #fff; } |
| 47 | input, select, textarea { padding: .3rem; border: 1px solid #b8bdc9; border-radius: 4px; } |
| 48 | .muted, .empty { color: #6b7385; } |
| 49 | .output, pre { background: #101624; color: #d7e0f5; padding: .75rem; border-radius: 4px; overflow: auto; white-space: pre-wrap; min-height: 3rem; } |
| 50 | </style> |
| 51 | </head> |
| 52 | <body> |
| 53 | <div id="playground"></div> |
| 54 | <script type="module"> |
| 55 | import { apiUrl, resourceDefinition } from '{$base}/es6/Apie.js'; |
| 56 | import { createBrowserPlayground } from '{$base}/es6/index.js'; |
| 57 | |
| 58 | window.playground = createBrowserPlayground(resourceDefinition, apiUrl).start('playground'); |
| 59 | </script> |
| 60 | </body> |
| 61 | </html> |
| 62 | HTML; |
| 63 | return new Response(200, ['Content-Type' => 'text/html; charset=utf-8'], $html); |
| 64 | } |
| 65 | } |