Last active
December 30, 2022 04:50
-
-
Save mwikala/5fd492447263fcf3a39dac7456e1ada9 to your computer and use it in GitHub Desktop.
Generate Ziggy.js Typescript Definitions — Laravel 9 and Vite
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copied from https://gist.github.com/iDevelopThings/aa0a288a4075371d875782c72f2c0389 | |
// This command will generate a file in resources/js/ called ziggy-shims.d.ts | |
// Make sure to install @types/ziggy-js for the type definitions used by the file generated | |
<?php | |
namespace App\Console\Commands; | |
use Illuminate\Console\Command; | |
use Illuminate\Filesystem\Filesystem; | |
use Illuminate\Support\Facades\Log; | |
use Tightenco\Ziggy\Ziggy; | |
class GenerateZiggyTypescriptDefinitions extends Command | |
{ | |
protected $signature = 'ziggy:typescript'; | |
protected $description = 'Generate TS definitions for ziggy'; | |
protected $files; | |
public function __construct(Filesystem $files) | |
{ | |
parent::__construct(); | |
$this->files = $files; | |
} | |
public function handle() | |
{ | |
$path = './resources/js/ziggy-shims.d.ts'; | |
$generatedRoutes = $this->generate(); | |
$this->makeDirectory($path); | |
$this->files->put(base_path($path), $generatedRoutes); | |
$this->info('File generated!'); | |
} | |
private function generate(): string | |
{ | |
$ziggy = (new Ziggy(false, null)); | |
$collectedRoutes = collect($ziggy->toArray()['routes']); | |
$routes = $collectedRoutes | |
->map(function ($route, $key) { | |
$methods = json_encode($route['methods'] ?? []); | |
return <<<TYPESCRIPT | |
"{$key}": { | |
"uri": "{$route['uri']}", | |
"methods": {$methods}, | |
}, | |
TYPESCRIPT; | |
}) | |
->join("\n"); | |
$params = $collectedRoutes->map(function ($route, $key) { | |
$matches = []; | |
preg_match_all('/(?<=\{)(.*?)(?=\})/', $route['uri'], $matches); | |
if (!count($matches) || !count($matches[0])) { | |
return <<<TYPESCRIPT | |
"{$key}": { | |
}, | |
TYPESCRIPT; | |
} else { | |
$unencodedParams = collect($matches[0])->reduce(function ($carry, $match) { | |
$carry[$match] = $match; | |
return $carry; | |
}, []); | |
$params = json_encode($unencodedParams); | |
return <<<TYPESCRIPT | |
"{$key}": | |
{$params} | |
, | |
TYPESCRIPT; | |
} | |
}) | |
->join("\n"); | |
//Log::debug($params); | |
return <<<TYPESCRIPT | |
import {Config, Router} from "ziggy-js"; | |
type LaravelRoutes = { | |
{$routes} | |
} | |
const LaravelParams = { | |
${params} | |
} | |
declare global { | |
declare interface ZiggyLaravelRoutes extends LaravelRoutes {} | |
declare function route(): Router; | |
declare function route<RouteKey extends keyof LaravelRoutes>(name: RouteKey, params?: LaravelRoutes[RouteKey], absolute?: boolean, customZiggy?: Config): string; | |
} | |
export { LaravelRoutes, LaravelParams }; | |
TYPESCRIPT; | |
} | |
protected function makeDirectory($path) | |
{ | |
if (!$this->files->isDirectory(dirname(base_path($path)))) { | |
$this->files->makeDirectory(dirname(base_path($path)), 0755, true, true); | |
} | |
return $path; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { defineConfig } from 'vite'; | |
import laravel from 'laravel-vite-plugin'; | |
import react from '@vitejs/plugin-react'; | |
import { exec } from 'child_process'; | |
export default defineConfig({ | |
plugins: [ | |
laravel({ | |
input: 'resources/js/app.tsx', | |
refresh: true, | |
}), | |
react(), | |
ziggy(), | |
], | |
}); | |
function ziggy(paths: Array<string> = ["routes/**/*.php"], enabled: boolean = true): import('vite').Plugin { | |
const generate = () => { | |
exec('php artisan ziggy:typescript', (_, stdout, __) => console.log(stdout)); | |
} | |
return { | |
name: 'ziggy-vite-plugin', | |
async buildStart() { | |
if (! enabled) { | |
return; | |
} | |
(await import ('chokidar')).watch(paths).on('change', (path) => { | |
console.log(`Ziggy: ${path} changed, regenerating...`); | |
generate(); | |
}) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment