diff --git a/resources/js/wayfinder.ts b/resources/js/wayfinder.ts index d01e750..6ff35da 100644 --- a/resources/js/wayfinder.ts +++ b/resources/js/wayfinder.ts @@ -11,6 +11,17 @@ export type QueryParams = Record< type Method = "get" | "post" | "put" | "delete" | "patch" | "head"; +declare global { + interface Window { + Wayfinder: { + defaultParameters: Record; + }; + } +} +window.Wayfinder = { + defaultParameters: {}, +} + export type RouteDefinition = { url: string; } & (TMethod extends Method[] ? { methods: TMethod } : { method: TMethod }); @@ -87,6 +98,26 @@ export const queryParams = (options?: RouteQueryOptions) => { return str.length > 0 ? `?${str}` : ""; }; +export const setDefaultParameters = (params: Record) => { + window.Wayfinder.defaultParameters = params; +}; + +export const addDefaultParameter = (key: string, value: string | number | boolean) => { + window.Wayfinder.defaultParameters[key] = value; +}; + +export const applyDefaultParameters = (existing: Record) => { + const existingParams = { ...existing } + + for (const key in window.Wayfinder.defaultParameters) { + if (existingParams[key] === undefined && window.Wayfinder.defaultParameters[key] !== undefined) { + existingParams[key] = window.Wayfinder.defaultParameters[key]; + } + } + + return existingParams; +}; + export const validateParameters = ( args: Record | undefined, optional: string[], diff --git a/resources/method.blade.ts b/resources/method.blade.ts index 37218c6..a49d015 100644 --- a/resources/method.blade.ts +++ b/resources/method.blade.ts @@ -31,6 +31,7 @@ @endforeach } } + args = applyDefaultParameters(args) @endif @if ($parameters->where('optional')->isNotEmpty()) diff --git a/src/GenerateCommand.php b/src/GenerateCommand.php index 40f3d1f..fdcced5 100644 --- a/src/GenerateCommand.php +++ b/src/GenerateCommand.php @@ -228,6 +228,10 @@ private function appendCommonImports(Collection $routes, string $path, string $n $imports[] = 'type RouteFormDefinition'; } + if ($routes->contains(fn (Route $route) => $route->parameters()->isNotEmpty())) { + $imports[] = 'applyDefaultParameters'; + } + if ($routes->contains(fn (Route $route) => $route->parameters()->contains(fn (Parameter $parameter) => $parameter->optional))) { $imports[] = 'validateParameters'; } diff --git a/tests/DefaultParameters.test.ts b/tests/DefaultParameters.test.ts new file mode 100644 index 0000000..1ddfa4e --- /dev/null +++ b/tests/DefaultParameters.test.ts @@ -0,0 +1,27 @@ +import { expect, test } from "vitest"; +import { defaultParametersDomain, dynamicDomain, fixedDomain } from "../workbench/resources/js/actions/App/Http/Controllers/DomainController"; +import { setDefaultParameters } from "../resources/js/wayfinder"; + +test('it can generate urls without default parameters set', () => { + expect(fixedDomain.url({ param: 'foo' })).toBe('//example.test/fixed-domain/foo') +}) + +test('it can generate urls with default parameters set on frontend', () => { + setDefaultParameters({ + domain: 'tim.macdonald', + }) + + expect(dynamicDomain.url({ + param: 'foo', + })).toBe('//tim.macdonald.au/dynamic-domain/foo') +}) + +test('it can generate urls with default URL parameters set on backend and frontend', () => { + setDefaultParameters({ + defaultDomain: 'tim.macdonald', + }) + + expect(defaultParametersDomain.url({ + param: 'foo', + })).toBe('//tim.macdonald.au/default-parameters-domain/foo') +}) \ No newline at end of file diff --git a/workbench/app/Http/Controllers/DomainController.php b/workbench/app/Http/Controllers/DomainController.php index e70dd71..f2ad8aa 100644 --- a/workbench/app/Http/Controllers/DomainController.php +++ b/workbench/app/Http/Controllers/DomainController.php @@ -13,4 +13,9 @@ public function dynamicDomain() { // } + + public function defaultParametersDomain() + { + // + } } diff --git a/workbench/app/Providers/WorkbenchServiceProvider.php b/workbench/app/Providers/WorkbenchServiceProvider.php index 5132268..7d38627 100644 --- a/workbench/app/Providers/WorkbenchServiceProvider.php +++ b/workbench/app/Providers/WorkbenchServiceProvider.php @@ -3,6 +3,7 @@ namespace App\Providers; use Illuminate\Support\Facades\Config; +use Illuminate\Support\Facades\URL; use Illuminate\Support\ServiceProvider; class WorkbenchServiceProvider extends ServiceProvider @@ -20,6 +21,10 @@ public function register(): void 'throw' => false, ], ]); + + URL::defaults([ + 'defaultDomain' => 'tim.macdonald', + ]); } /** diff --git a/workbench/routes/web.php b/workbench/routes/web.php index 50f89ff..022dd52 100644 --- a/workbench/routes/web.php +++ b/workbench/routes/web.php @@ -59,6 +59,7 @@ Route::domain('example.test')->get('/fixed-domain/{param}', [DomainController::class, 'fixedDomain']); Route::domain('{domain}.au')->get('/dynamic-domain/{param}', [DomainController::class, 'dynamicDomain']); +Route::domain('{defaultDomain}.au')->get('/default-parameters-domain/{param}', [DomainController::class, 'defaultParametersDomain']); Route::get('/nested/controller', [NestedController::class, 'nested']);