22
33namespace Appwrite \SDK \Language ;
44
5- class Web extends JS {
5+ use Twig \TwigFilter ;
6+
7+ class Web extends JS
8+ {
69
710 /**
811 * @return string
@@ -20,8 +23,38 @@ public function getFiles()
2023 return [
2124 [
2225 'scope ' => 'default ' ,
23- 'destination ' => 'src/sdk.ts ' ,
24- 'template ' => '/web/src/sdk.ts.twig ' ,
26+ 'destination ' => 'src/index.ts ' ,
27+ 'template ' => 'web/src/index.ts.twig ' ,
28+ 'minify ' => false ,
29+ ],
30+ [
31+ 'scope ' => 'default ' ,
32+ 'destination ' => 'src/client.ts ' ,
33+ 'template ' => 'web/src/client.ts.twig ' ,
34+ 'minify ' => false ,
35+ ],
36+ [
37+ 'scope ' => 'default ' ,
38+ 'destination ' => 'src/service.ts ' ,
39+ 'template ' => 'web/src/service.ts.twig ' ,
40+ 'minify ' => false ,
41+ ],
42+ [
43+ 'scope ' => 'service ' ,
44+ 'destination ' => 'src/services/{{service.name | caseDash}}.ts ' ,
45+ 'template ' => 'web/src/services/template.ts.twig ' ,
46+ 'minify ' => false ,
47+ ],
48+ [
49+ 'scope ' => 'default ' ,
50+ 'destination ' => 'src/models.ts ' ,
51+ 'template ' => 'web/src/models.ts.twig ' ,
52+ 'minify ' => false ,
53+ ],
54+ [
55+ 'scope ' => 'default ' ,
56+ 'destination ' => 'src/query.ts ' ,
57+ 'template ' => 'web/src/query.ts.twig ' ,
2558 'minify ' => false ,
2659 ],
2760 [
@@ -98,7 +131,7 @@ public function getParamExample(array $param)
98131
99132 $ output = '' ;
100133
101- if (empty ($ example ) && $ example !== 0 && $ example !== false ) {
134+ if (empty ($ example ) && $ example !== 0 && $ example !== false ) {
102135 switch ($ type ) {
103136 case self ::TYPE_NUMBER :
104137 case self ::TYPE_INTEGER :
@@ -118,8 +151,7 @@ public function getParamExample(array $param)
118151 $ output .= "document.getElementById('uploader').files[0] " ;
119152 break ;
120153 }
121- }
122- else {
154+ } else {
123155 switch ($ type ) {
124156 case self ::TYPE_NUMBER :
125157 case self ::TYPE_INTEGER :
@@ -141,4 +173,170 @@ public function getParamExample(array $param)
141173
142174 return $ output ;
143175 }
176+
177+ public function getTypeName ($ type , $ method = []): string
178+ {
179+ switch ($ type ) {
180+ case self ::TYPE_INTEGER :
181+ case self ::TYPE_NUMBER :
182+ return 'number ' ;
183+ break ;
184+ case self ::TYPE_ARRAY :
185+ return 'string[] ' ;
186+ case self ::TYPE_FILE :
187+ return 'File ' ;
188+ case self ::TYPE_OBJECT :
189+ if (empty ($ method )) {
190+ return $ type ;
191+ }
192+
193+ switch ($ method ['responseModel ' ]) {
194+ case 'user ' :
195+ return "Partial<Preferences> " ;
196+ break ;
197+ case 'document ' :
198+ if ($ method ['method ' ] === 'post ' ) {
199+ return "Omit<Document, keyof Models.Document> " ;
200+ }
201+ if ($ method ['method ' ] === 'patch ' ) {
202+ return "Partial<Omit<Document, keyof Models.Document>> " ;
203+ }
204+ }
205+ break ;
206+ }
207+
208+ return $ type ;
209+ }
210+
211+ protected function populateGenerics (string $ model , array $ spec , array &$ generics , bool $ skipFirst = false )
212+ {
213+ if (!$ skipFirst && $ spec ['definitions ' ][$ model ]['additionalProperties ' ]) {
214+ $ generics [] = $ this ->toUpperCase ($ model );
215+ }
216+
217+ $ properties = $ spec ['definitions ' ][$ model ]['properties ' ];
218+
219+ foreach ($ properties as $ property ) {
220+ if (array_key_exists ('sub_schema ' , $ property ) && $ property ['sub_schema ' ]) {
221+ $ this ->populateGenerics ($ property ['sub_schema ' ], $ spec , $ generics , false );
222+ }
223+ }
224+ }
225+
226+ public function getGenerics (string $ model , array $ spec , bool $ skipFirst = false ): string
227+ {
228+ $ generics = [];
229+
230+ if (array_key_exists ($ model , $ spec ['definitions ' ])) {
231+ $ this ->populateGenerics ($ model , $ spec , $ generics , $ skipFirst );
232+ }
233+
234+ if (empty ($ generics )) return '' ;
235+
236+ $ generics = array_unique ($ generics );
237+ $ generics = array_map (fn ($ type ) => "{$ type } extends Models. {$ type }" , $ generics );
238+
239+ return '< ' . implode (', ' , $ generics ) . '> ' ;
240+ }
241+
242+ public function getReturn (array $ method , array $ spec ): string
243+ {
244+ if ($ method ['type ' ] === 'webAuth ' ) {
245+ return 'void | URL ' ;
246+ } elseif ($ method ['type ' ] === 'location ' ) {
247+ return 'URL ' ;
248+ }
249+
250+ if (array_key_exists ('responseModel ' , $ method ) && !empty ($ method ['responseModel ' ]) && $ method ['responseModel ' ] !== 'any ' ) {
251+ $ ret = 'Promise< ' ;
252+
253+ if (
254+ array_key_exists ($ method ['responseModel ' ], $ spec ['definitions ' ]) &&
255+ array_key_exists ('additionalProperties ' , $ spec ['definitions ' ][$ method ['responseModel ' ]]) &&
256+ !$ spec ['definitions ' ][$ method ['responseModel ' ]]['additionalProperties ' ]
257+ ) {
258+ $ ret .= 'Models. ' ;
259+ }
260+
261+ $ ret .= $ this ->toUpperCase ($ method ['responseModel ' ]);
262+
263+ $ models = [];
264+
265+ if ($ method ['responseModel ' ]) {
266+ $ this ->populateGenerics ($ method ['responseModel ' ], $ spec , $ models );
267+ }
268+
269+ $ models = array_unique ($ models );
270+ $ models = array_filter ($ models , fn ($ model ) => $ model != $ this ->toUpperCase ($ method ['responseModel ' ]));
271+
272+ if (!empty ($ models )) {
273+ $ ret .= '< ' . implode (', ' , $ models ) . '> ' ;
274+ }
275+
276+ $ ret .= '> ' ;
277+
278+ return $ ret ;
279+ } else {
280+ return 'Promise<{}> ' ;
281+ }
282+
283+ return "" ;
284+ }
285+
286+ public function toUpperCase (string $ value ): string
287+ {
288+ return ucfirst ((string )$ this ->helperCamelCase ($ value ));
289+ }
290+
291+ protected function helperCamelCase ($ str )
292+ {
293+ $ str = preg_replace ('/[^a-z0-9 ' . implode ("" , []) . ']+/i ' , ' ' , $ str );
294+ $ str = trim ($ str );
295+ $ str = ucwords ($ str );
296+ $ str = str_replace (" " , "" , $ str );
297+ $ str = lcfirst ($ str );
298+
299+ return $ str ;
300+ }
301+
302+ public function getSubSchema (array $ property , array $ spec ): string
303+ {
304+ if (array_key_exists ('sub_schema ' , $ property )) {
305+ $ ret = '' ;
306+ $ generics = [];
307+ $ this ->populateGenerics ($ property ['sub_schema ' ], $ spec , $ generics );
308+
309+ $ generics = array_filter ($ generics , fn ($ model ) => $ model != $ this ->toUpperCase ($ property ['sub_schema ' ]));
310+
311+ $ ret .= $ this ->toUpperCase ($ property ['sub_schema ' ]);
312+ if (!empty ($ generics )) {
313+ $ ret .= '< ' . implode (', ' , $ generics ) . '> ' ;
314+ }
315+ if ($ property ['type ' ] === 'array ' ) {
316+ $ ret .= '[] ' ;
317+ }
318+
319+ return $ ret ;
320+ }
321+
322+ return $ this ->getTypeName ($ property ['type ' ]);
323+ }
324+
325+ public function getFilters (): array
326+ {
327+ return [
328+ new TwigFilter ('getPropertyType ' , function ($ value , $ method = []) {
329+ return $ this ->getTypeName ($ value , $ method );
330+ }),
331+ new TwigFilter ('getSubSchema ' , function (array $ property , array $ spec ) {
332+ return $ this ->getSubSchema ($ property , $ spec );
333+ }),
334+ new TwigFilter ('getGenerics ' , function (string $ model , array $ spec , bool $ skipAdditional = false ) {
335+ return $ this ->getGenerics ($ model , $ spec , $ skipAdditional );
336+ }),
337+ new TwigFilter ('getReturn ' , function (array $ method , array $ spec ) {
338+ return $ this ->getReturn ($ method , $ spec );
339+ }),
340+ ];
341+ }
144342}
0 commit comments