|
4 | 4 |
|
5 | 5 | use Spatie\TypeScriptTransformer\DefaultTypeProviders\DefaultTypesProvider;
|
6 | 6 | use Spatie\TypeScriptTransformer\Laravel\Actions\ResolveLaravelRoutControllerCollectionsAction;
|
| 7 | +use Spatie\TypeScriptTransformer\Laravel\Routes\RouteCollection; |
7 | 8 | use Spatie\TypeScriptTransformer\Laravel\Routes\RouteController;
|
8 | 9 | use Spatie\TypeScriptTransformer\Laravel\Routes\RouteControllerAction;
|
9 |
| -use Spatie\TypeScriptTransformer\Laravel\Routes\RouteControllerCollection; |
10 | 10 | use Spatie\TypeScriptTransformer\Laravel\Routes\RouteInvokableController;
|
11 | 11 | use Spatie\TypeScriptTransformer\Laravel\Routes\RouteParameter;
|
12 | 12 | use Spatie\TypeScriptTransformer\Laravel\Routes\RouteParameterCollection;
|
| 13 | +use Spatie\TypeScriptTransformer\References\CustomReference; |
13 | 14 | use Spatie\TypeScriptTransformer\Transformed\Transformed;
|
| 15 | +use Spatie\TypeScriptTransformer\TypeScript\TypeReference; |
14 | 16 | use Spatie\TypeScriptTransformer\TypeScript\TypeScriptAlias;
|
15 | 17 | use Spatie\TypeScriptTransformer\TypeScript\TypeScriptArray;
|
16 | 18 | use Spatie\TypeScriptTransformer\TypeScript\TypeScriptConditional;
|
|
30 | 32 | use Spatie\TypeScriptTransformer\TypeScript\TypeScriptString;
|
31 | 33 | use Spatie\TypeScriptTransformer\TypeScript\TypeScriptUnion;
|
32 | 34 |
|
33 |
| -// @todo implement the method, probably using a RawTypeScriptNode, creating individual notes for each JS construct is probably a bit far fetched |
34 |
| -// @todo make sure we support __invoke routes without action |
35 |
| -// @todo add support for nullable parameters, these should be inferred |
36 |
| - |
37 |
| -/** |
38 |
| - * function route< |
39 |
| - * TController extends keyof Routes, |
40 |
| - * TAction extends keyof Routes[TController], |
41 |
| - * TParams extends Routes[TController][TAction]["parameters"] |
42 |
| - * >(action: [TController, TAction] | TController, params?: TParams): string { |
43 |
| - * |
44 |
| - * } |
45 |
| - */ |
46 | 35 | class LaravelActionDefaultTypesProvider implements DefaultTypesProvider
|
47 | 36 | {
|
48 | 37 | public function __construct(
|
49 |
| - protected ResolveLaravelRoutControllerCollectionsAction $resolveLaravelRoutControllerCollectionsAction = new ResolveLaravelRoutControllerCollectionsAction() |
| 38 | + protected ResolveLaravelRoutControllerCollectionsAction $resolveLaravelRoutControllerCollectionsAction = new ResolveLaravelRoutControllerCollectionsAction(), |
| 39 | + protected ?string $defaultNamespace = null, |
| 40 | + protected array $location = [], |
50 | 41 | ) {
|
51 | 42 | }
|
52 | 43 |
|
53 | 44 | public function provide(): array
|
54 | 45 | {
|
55 |
| - $controllers = $this->resolveLaravelRoutControllerCollectionsAction->execute(); |
| 46 | + $controllers = $this->resolveLaravelRoutControllerCollectionsAction->execute( |
| 47 | + $this->defaultNamespace, |
| 48 | + includeRouteClosures: false, |
| 49 | + ); |
56 | 50 |
|
57 | 51 | $transformedRoutes = new Transformed(
|
58 | 52 | new TypeScriptAlias(
|
59 |
| - new TypeScriptIdentifier('Routes'), |
| 53 | + new TypeScriptIdentifier('RoutesList'), |
60 | 54 | $this->parseRouteControllerCollection($controllers),
|
61 | 55 | ),
|
62 |
| - null, |
63 |
| - 'Routes', |
| 56 | + $routesListReference = new CustomReference('laravel_route_actions', 'routes_list'), |
| 57 | + 'RoutesList', |
64 | 58 | true,
|
65 |
| - [], |
| 59 | + $this->location, |
66 | 60 | );
|
67 | 61 |
|
68 |
| - $actionParam = new Transformed( |
| 62 | + $isInvokableControllerCondition = TypeScriptOperator::extends( |
| 63 | + new TypeScriptIndexedAccess( |
| 64 | + new TypeReference($routesListReference), |
| 65 | + [new TypeScriptIdentifier('TController')], |
| 66 | + ), |
| 67 | + new TypeScriptObject([ |
| 68 | + new TypeScriptProperty('invokable', new TypeScriptRaw('true')), |
| 69 | + ]) |
| 70 | + ); |
| 71 | + |
| 72 | + $actionController = new Transformed( |
69 | 73 | new TypeScriptAlias(
|
70 | 74 | new TypeScriptGeneric(
|
71 |
| - new TypeScriptIdentifier('ActionParam'), |
| 75 | + new TypeScriptIdentifier('ActionController'), |
72 | 76 | [
|
73 | 77 | new TypeScriptGenericTypeVariable(new TypeScriptIdentifier('TController')),
|
74 | 78 | new TypeScriptGenericTypeVariable(new TypeScriptIdentifier('TAction')),
|
75 | 79 | ]
|
76 | 80 | ),
|
77 | 81 | new TypeScriptConditional(
|
78 |
| - TypeScriptOperator::extends( |
79 |
| - new TypeScriptIndexedAccess( |
80 |
| - new TypeScriptIdentifier('Routes'), |
81 |
| - [new TypeScriptIdentifier('TController')], |
82 |
| - ), |
83 |
| - new TypeScriptObject([ |
84 |
| - new TypeScriptProperty('invokable', new TypeScriptRaw('true')), |
85 |
| - ]) |
86 |
| - ), |
| 82 | + $isInvokableControllerCondition, |
87 | 83 | new TypeScriptIdentifier('TController'),
|
88 | 84 | new TypeScriptArray([
|
89 | 85 | new TypeScriptIdentifier('TController'),
|
90 | 86 | new TypeScriptIdentifier('TAction'),
|
91 | 87 | ])
|
92 | 88 | )
|
93 | 89 | ),
|
94 |
| - null, |
95 |
| - 'ActionParam', |
| 90 | + $actionControllerReference = new CustomReference('laravel_route_actions', 'action_controller'), |
| 91 | + 'ActionController', |
96 | 92 | true,
|
97 |
| - [], |
| 93 | + $this->location, |
98 | 94 | );
|
99 | 95 |
|
| 96 | + $actionParameters = new Transformed( |
| 97 | + new TypeScriptAlias( |
| 98 | + new TypeScriptGeneric( |
| 99 | + new TypeScriptIdentifier('ActionParameters'), |
| 100 | + [ |
| 101 | + new TypeScriptGenericTypeVariable(new TypeScriptIdentifier('TController')), |
| 102 | + new TypeScriptGenericTypeVariable(new TypeScriptIdentifier('TAction')), |
| 103 | + ] |
| 104 | + ), |
| 105 | + new TypeScriptConditional( |
| 106 | + $isInvokableControllerCondition, |
| 107 | + new TypeScriptIndexedAccess(new TypeReference($routesListReference), [ |
| 108 | + new TypeScriptIdentifier('TController'), |
| 109 | + new TypeScriptIdentifier('"parameters"'), |
| 110 | + ]), |
| 111 | + new TypeScriptIndexedAccess(new TypeReference($routesListReference), [ |
| 112 | + new TypeScriptIdentifier('TController'), |
| 113 | + new TypeScriptIdentifier('"actions"'), |
| 114 | + new TypeScriptIdentifier('TAction'), |
| 115 | + new TypeScriptIdentifier('"parameters"'), |
| 116 | + ]) |
| 117 | + ) |
| 118 | + ), |
| 119 | + $actionParametersReference = new CustomReference('laravel_route_actions', 'action_parameters'), |
| 120 | + 'ActionParameters', |
| 121 | + true, |
| 122 | + $this->location, |
| 123 | + ); |
| 124 | + |
| 125 | + $jsonEncodedRoutes = json_encode($controllers->toJsObject(), flags: JSON_UNESCAPED_SLASHES); |
| 126 | + $baseUrl = url('/'); |
| 127 | + |
100 | 128 | $transformedAction = new Transformed(
|
101 | 129 | new TypeScriptFunctionDefinition(
|
102 | 130 | new TypeScriptGeneric(
|
103 | 131 | new TypeScriptIdentifier('action'),
|
104 | 132 | [
|
105 | 133 | new TypeScriptGenericTypeVariable(
|
106 | 134 | new TypeScriptIdentifier('TController'),
|
107 |
| - extends: new TypeScriptIdentifier('keyof Routes'), |
| 135 | + extends: TypeScriptOperator::keyof(new TypeReference($routesListReference)) |
108 | 136 | ),
|
109 | 137 | new TypeScriptGenericTypeVariable(
|
110 | 138 | new TypeScriptIdentifier('TAction'),
|
111 |
| - extends: new TypeScriptIdentifier('keyof Routes[TController]["actions"]'), |
| 139 | + extends: TypeScriptOperator::keyof(new TypeScriptIndexedAccess(new TypeReference($routesListReference), [ |
| 140 | + new TypeScriptIdentifier('TController'), |
| 141 | + new TypeScriptIdentifier('"actions"'), |
| 142 | + ])) |
112 | 143 | ),
|
113 | 144 | new TypeScriptGenericTypeVariable(
|
114 | 145 | new TypeScriptIdentifier('TParams'),
|
115 |
| - extends: new TypeScriptIdentifier('Routes[TController]["actions"][TAction]["parameters"]'), |
| 146 | + extends: new TypeScriptIndexedAccess(new TypeReference($routesListReference), [ |
| 147 | + new TypeScriptIdentifier('TController'), |
| 148 | + new TypeScriptIdentifier('"actions"'), |
| 149 | + new TypeScriptIdentifier('TAction'), |
| 150 | + new TypeScriptIdentifier('"parameters"'), |
| 151 | + ]) |
116 | 152 | ),
|
117 | 153 | ]
|
118 | 154 | ),
|
119 | 155 | [
|
120 | 156 | new TypeScriptParameter('action', new TypeScriptGeneric(
|
121 |
| - new TypeScriptIdentifier('ActionParam'), |
| 157 | + new TypeReference($actionControllerReference), |
122 | 158 | [
|
123 | 159 | new TypeScriptGenericTypeVariable(new TypeScriptIdentifier('TController')),
|
124 | 160 | new TypeScriptGenericTypeVariable(new TypeScriptIdentifier('TAction')),
|
125 | 161 | ]
|
126 | 162 | )),
|
127 |
| - new TypeScriptParameter('params', new TypeScriptIdentifier('TParams'), isOptional: true), |
| 163 | + new TypeScriptParameter('parameters', new TypeScriptGeneric( |
| 164 | + new TypeReference($actionParametersReference), |
| 165 | + [ |
| 166 | + new TypeScriptGenericTypeVariable(new TypeScriptIdentifier('TController')), |
| 167 | + new TypeScriptGenericTypeVariable(new TypeScriptIdentifier('TAction')), |
| 168 | + ] |
| 169 | + ), isOptional: true), |
128 | 170 | ],
|
129 | 171 | new TypeScriptString(),
|
130 |
| - new TypeScriptRaw("let routes = JSON.parse('".json_encode($controllers->toJsObject(), flags: JSON_UNESCAPED_SLASHES)."')") |
| 172 | + new TypeScriptRaw(<<<TS |
| 173 | +let routes = JSON.parse('$jsonEncodedRoutes'); |
| 174 | +let baseUrl = '$baseUrl'; |
| 175 | +
|
| 176 | +let found = typeof action === 'string' |
| 177 | + ? routes.controllers[action] |
| 178 | + : routes.controllers[action[0]]['actions'][action[1]]; |
| 179 | +
|
| 180 | +let url = baseUrl + '/' + found.url; |
| 181 | +
|
| 182 | +if(parameters) { |
| 183 | + for(let parameter in parameters) { |
| 184 | + url = url.replace('{' + parameter + '}', parameters[parameter]); |
| 185 | + } |
| 186 | +} |
| 187 | +
|
| 188 | +return url; |
| 189 | +TS |
| 190 | +) |
| 191 | +// new TypeScriptRaw("let routes = JSON.parse('".json_encode($controllers->toJsObject(), flags: JSON_UNESCAPED_SLASHES)."')") |
131 | 192 | ),
|
132 |
| - null, |
| 193 | + new CustomReference('laravel_route_actions', 'action_function'), |
133 | 194 | 'action',
|
134 | 195 | true,
|
135 |
| - [], |
| 196 | + $this->location, |
136 | 197 | );
|
137 | 198 |
|
138 |
| - return [$transformedRoutes, $actionParam, $transformedAction]; |
| 199 | + return [$transformedRoutes, $actionController, $actionParameters, $transformedAction]; |
139 | 200 | }
|
140 | 201 |
|
141 |
| - protected function parseRouteControllerCollection(RouteControllerCollection $collection): TypeScriptNode |
| 202 | + protected function parseRouteControllerCollection(RouteCollection $collection): TypeScriptNode |
142 | 203 | {
|
143 | 204 | return new TypeScriptObject(collect($collection->controllers)->map(function (RouteController|RouteInvokableController $controller, string $name) {
|
144 | 205 | return new TypeScriptProperty(
|
|
0 commit comments