Skip to content

Commit 858ff87

Browse files
Merge pull request #72 from istiak-tridip/fix/bugs
Resolve multiple bugs
2 parents e826953 + 6b293fa commit 858ff87

File tree

6 files changed

+56
-13
lines changed

6 files changed

+56
-13
lines changed

resources/method.blade.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@include('wayfinder::docblock')
2-
{!! when(($export ?? true) && !$isInvokable, 'export ') !!}const {!! $method !!} = (@include('wayfinder::function-arguments')): RouteDefinition<@js($verbs->first()->actual)> => ({
2+
{!! when($shouldExport, 'export ') !!}const {!! $method !!} = (@include('wayfinder::function-arguments')): RouteDefinition<@js($verbs->first()->actual)> => ({
33
url: {!! $method !!}.url({!! when($parameters->isNotEmpty(), 'args, ') !!}options),
44
method: @js($verbs->first()->actual),
55
})

resources/multi-method.blade.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
...$route,
44
'method' => $route['tempMethod'],
55
'docblock_method' => $route['method'],
6-
'export' => false,
6+
'shouldExport' => false,
77
])
88
@endforeach
99

10-
{!! when(!$isInvokable, 'export ') !!}const {!! $method !!} = {
10+
{!! when($shouldExport, 'export ') !!}const {!! $method !!} = {
1111
@foreach ($routes as $route)
1212
{!! $route['uri'] !!}: {!! $route['tempMethod'] !!},
1313
@endforeach

src/GenerateCommand.php

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ private function writeControllerFile(Collection $routes, string $namespace): voi
157157

158158
if ($invokable->isEmpty()) {
159159
$exportedMethods = $methods->map(fn (Route $route) => $route->jsMethod());
160-
$reservedMethods = $methods->filter(fn (Route $route) => $route->originalJsMethod() !== $route->jsMethod())->map(fn (Route $route) => $route->originalJsMethod().': '.$route->jsMethod());
160+
$reservedMethods = $methods->filter(fn (Route $route) => $route->originalJsMethod() !== $route->jsMethod())->map(fn (Route $route) => TypeScript::quoteIfNeeded($route->originalJsMethod()).': '.$route->jsMethod());
161161
$exportedMethods = $exportedMethods->merge($reservedMethods);
162162

163163
$methodProps = "const {$defaultExport} = { ";
@@ -176,17 +176,20 @@ private function writeControllerFile(Collection $routes, string $namespace): voi
176176

177177
private function writeMultiRouteControllerMethodExport(Collection $routes, string $path): void
178178
{
179+
$isInvokable = $routes->first()->hasInvokableController();
180+
179181
$this->appendContent($path, $this->view->make('wayfinder::multi-method', [
180182
'method' => $routes->first()->jsMethod(),
181183
'original_method' => $routes->first()->originalJsMethod(),
182184
'path' => $routes->first()->controllerPath(),
183185
'line' => $routes->first()->controllerMethodLineNumber(),
184186
'controller' => $routes->first()->controller(),
185-
'isInvokable' => $routes->first()->hasInvokableController(),
187+
'isInvokable' => $isInvokable,
188+
'shouldExport' => ! $isInvokable,
186189
'withForm' => $this->option('with-form') ?? false,
187190
'routes' => $routes->map(fn ($r) => [
188191
'method' => $r->jsMethod(),
189-
'tempMethod' => $r->jsMethod().md5($r->uri()),
192+
'tempMethod' => $r->jsMethod().hash('xxh128', $r->uri()),
190193
'parameters' => $r->parameters(),
191194
'verbs' => $r->verbs(),
192195
'uri' => $r->uri(),
@@ -201,6 +204,7 @@ private function writeControllerMethodExport(Route $route, string $path): void
201204
'method' => $route->jsMethod(),
202205
'original_method' => $route->originalJsMethod(),
203206
'isInvokable' => $route->hasInvokableController(),
207+
'shouldExport' => ! $route->hasInvokableController(),
204208
'path' => $route->controllerPath(),
205209
'line' => $route->controllerMethodLineNumber(),
206210
'parameters' => $route->parameters(),
@@ -255,7 +259,8 @@ private function writeNamedMethodExport(Route $route, string $path): void
255259
'controller' => $route->controller(),
256260
'method' => $route->namedMethod(),
257261
'original_method' => $route->originalJsMethod(),
258-
'isInvokable' => false,
262+
'isInvokable' => $route->hasInvokableController(),
263+
'shouldExport' => ! $route->hasInvokableController() || str_contains($route->controller(), '\\Closure'),
259264
'path' => $route->controllerPath(),
260265
'line' => $route->controllerMethodLineNumber(),
261266
'parameters' => $route->parameters(),
@@ -273,14 +278,12 @@ private function writeBarrelFiles(array|Collection $children, string $parent): v
273278
return;
274279
}
275280

276-
$normalizeToCamelCase = fn ($value) => str_contains($value, '-') ? Str::camel($value) : $value;
277-
278281
$indexPath = join_paths($this->base(), $parent, 'index.ts');
279282

280283
$childKeys = $children->keys()->mapWithKeys(fn ($child) => [
281284
$child => [
282-
'safe' => TypeScript::safeMethod($normalizeToCamelCase($child), 'Method'),
283-
'normalized' => $normalizeToCamelCase($child),
285+
'safe' => TypeScript::safeMethod($child, 'Method'),
286+
'normalized' => str($child)->whenContains('-', fn ($s) => $s->camel())->toString(),
284287
],
285288
]);
286289

@@ -297,7 +300,7 @@ private function writeBarrelFiles(array|Collection $children, string $parent): v
297300

298301
$keys = $childKeys->map(fn ($alias, $key) => str_repeat(' ', 4).implode(': ', array_unique([$alias['normalized'], $alias['safe']])))->implode(', '.PHP_EOL);
299302

300-
$varExport = $normalizeToCamelCase(Str::afterLast($parent, DIRECTORY_SEPARATOR));
303+
$varExport = TypeScript::safeMethod(Str::afterLast($parent, DIRECTORY_SEPARATOR), 'Method');
301304

302305
$this->appendContent($indexPath, <<<JAVASCRIPT
303306

src/TypeScript.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
class TypeScript
88
{
99
public const RESERVED_KEYWORDS = [
10+
'await',
1011
'break',
1112
'case',
1213
'catch',
@@ -18,19 +19,28 @@ class TypeScript
1819
'delete',
1920
'do',
2021
'else',
22+
'enum',
2123
'export',
2224
'extends',
2325
'false',
2426
'finally',
2527
'for',
2628
'function',
2729
'if',
30+
'implements',
2831
'import',
2932
'in',
3033
'instanceof',
34+
'interface',
35+
'let',
3136
'new',
3237
'null',
38+
'package',
39+
'private',
40+
'protected',
41+
'public',
3342
'return',
43+
'static',
3444
'super',
3545
'switch',
3646
'this',
@@ -42,6 +52,7 @@ class TypeScript
4252
'void',
4353
'while',
4454
'with',
55+
'yield',
4556
];
4657

4758
public static function safeMethod(string $method, string $suffix): string
@@ -58,13 +69,26 @@ public static function safeMethod(string $method, string $suffix): string
5869
return $method->append(ucfirst($suffix));
5970
}
6071

61-
if (is_numeric((string) $method)) {
72+
if ($method->match('/^[a-zA-Z_$]/')->isEmpty()) {
6273
return $method->prepend($suffix);
6374
}
6475

6576
return $method;
6677
}
6778

79+
public static function quoteIfNeeded(string $name): string
80+
{
81+
if (is_numeric($name)) {
82+
return $name;
83+
}
84+
85+
if (is_numeric($name[0])) {
86+
return '"'.$name.'"';
87+
}
88+
89+
return $name;
90+
}
91+
6892
public static function cleanUp(string $view): string
6993
{
7094
$replacements = [

tests/DisallowedMethodNames.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import DisallowedMethodNameController, {
33
deleteMethod,
44
method404,
55
} from "../workbench/resources/js/actions/App/Http/Controllers/DisallowedMethodNameController";
6+
import method2fa from "../workbench/resources/js/routes/2fa";
7+
import defaultMethod from "../workbench/resources/js/routes/default";
68
import disallowed from "../workbench/resources/js/routes/disallowed";
79

810
test("will append `method` to invalid methods", () => {
@@ -17,3 +19,15 @@ test("will append `method` to invalid methods", () => {
1719
test("will append `method` to invalid methods", () => {
1820
expect(disallowed[404].url()).toBe("/disallowed/404");
1921
});
22+
23+
test("will properly handle leading numbers", () => {
24+
expect(method2fa.disallowed.url()).toBe("/disallowed/2fa");
25+
expect(DisallowedMethodNameController["2fa"].url()).toBe("/disallowed/2fa");
26+
});
27+
28+
test("will properly handle reserved JS words", () => {
29+
expect(defaultMethod.login.url()).toBe("/disallowed/default");
30+
expect(DisallowedMethodNameController["default"].url()).toBe(
31+
"/disallowed/default",
32+
);
33+
});

workbench/routes/web.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@
6767

6868
Route::get('/disallowed/delete', [DisallowedMethodNameController::class, 'delete']);
6969
Route::get('/disallowed/404', [DisallowedMethodNameController::class, '404'])->name('disallowed.404');
70+
Route::get('/disallowed/2fa', [DisallowedMethodNameController::class, '2fa'])->name('2fa.disallowed');
71+
Route::get('/disallowed/default', [DisallowedMethodNameController::class, 'default'])->name('default.login');
7072

7173
Route::get('/anonymous-middleware', [AnonymousMiddlewareController::class, 'show']);
7274

0 commit comments

Comments
 (0)