@@ -200,3 +200,168 @@ export function buildRequestsOutputPath(outputPath: string) {
200
200
export function buildQueriesOutputPath ( outputPath : string ) {
201
201
return path . join ( outputPath , queriesOutputPath ) ;
202
202
}
203
+
204
+ export function getQueryKeyFnName ( queryKey : string ) {
205
+ return `${ capitalizeFirstLetter ( queryKey ) } Fn` ;
206
+ }
207
+
208
+ /**
209
+ * Create QueryKey/MutationKey exports
210
+ */
211
+ export function createQueryKeyExport ( {
212
+ methodName,
213
+ queryKey,
214
+ } : {
215
+ methodName : string ;
216
+ queryKey : string ;
217
+ } ) {
218
+ return ts . factory . createVariableStatement (
219
+ [ ts . factory . createModifier ( ts . SyntaxKind . ExportKeyword ) ] ,
220
+ ts . factory . createVariableDeclarationList (
221
+ [
222
+ ts . factory . createVariableDeclaration (
223
+ ts . factory . createIdentifier ( queryKey ) ,
224
+ undefined ,
225
+ undefined ,
226
+ ts . factory . createStringLiteral (
227
+ `${ capitalizeFirstLetter ( methodName ) } ` ,
228
+ ) ,
229
+ ) ,
230
+ ] ,
231
+ ts . NodeFlags . Const ,
232
+ ) ,
233
+ ) ;
234
+ }
235
+
236
+ export function createQueryKeyFnExport (
237
+ queryKey : string ,
238
+ method : VariableDeclaration ,
239
+ type : "query" | "mutation" = "query" ,
240
+ ) {
241
+ // Mutation keys don't require clientOptions
242
+ const params = type === "query" ? getRequestParamFromMethod ( method ) : null ;
243
+
244
+ // override key is used to allow the user to override the the queryKey values
245
+ const overrideKey = ts . factory . createParameterDeclaration (
246
+ undefined ,
247
+ undefined ,
248
+ ts . factory . createIdentifier ( type === "query" ? "queryKey" : "mutationKey" ) ,
249
+ QuestionToken ,
250
+ ts . factory . createTypeReferenceNode ( "Array<unknown>" , [ ] ) ,
251
+ ) ;
252
+
253
+ return ts . factory . createVariableStatement (
254
+ [ ts . factory . createModifier ( ts . SyntaxKind . ExportKeyword ) ] ,
255
+ ts . factory . createVariableDeclarationList (
256
+ [
257
+ ts . factory . createVariableDeclaration (
258
+ ts . factory . createIdentifier ( getQueryKeyFnName ( queryKey ) ) ,
259
+ undefined ,
260
+ undefined ,
261
+ ts . factory . createArrowFunction (
262
+ undefined ,
263
+ undefined ,
264
+ params ? [ params , overrideKey ] : [ overrideKey ] ,
265
+ undefined ,
266
+ EqualsOrGreaterThanToken ,
267
+ type === "query"
268
+ ? queryKeyFn ( queryKey , method )
269
+ : mutationKeyFn ( queryKey ) ,
270
+ ) ,
271
+ ) ,
272
+ ] ,
273
+ ts . NodeFlags . Const ,
274
+ ) ,
275
+ ) ;
276
+ }
277
+
278
+ function queryKeyFn (
279
+ queryKey : string ,
280
+ method : VariableDeclaration ,
281
+ ) : ts . Expression {
282
+ return ts . factory . createArrayLiteralExpression (
283
+ [
284
+ ts . factory . createIdentifier ( queryKey ) ,
285
+ ts . factory . createSpreadElement (
286
+ ts . factory . createParenthesizedExpression (
287
+ ts . factory . createBinaryExpression (
288
+ ts . factory . createIdentifier ( "queryKey" ) ,
289
+ ts . factory . createToken ( ts . SyntaxKind . QuestionQuestionToken ) ,
290
+ getVariableArrowFunctionParameters ( method )
291
+ ? // [...clientOptions]
292
+ ts . factory . createArrayLiteralExpression ( [
293
+ ts . factory . createIdentifier ( "clientOptions" ) ,
294
+ ] )
295
+ : // []
296
+ ts . factory . createArrayLiteralExpression ( ) ,
297
+ ) ,
298
+ ) ,
299
+ ) ,
300
+ ] ,
301
+ false ,
302
+ ) ;
303
+ }
304
+
305
+ function mutationKeyFn ( mutationKey : string ) : ts . Expression {
306
+ return ts . factory . createArrayLiteralExpression (
307
+ [
308
+ ts . factory . createIdentifier ( mutationKey ) ,
309
+ ts . factory . createSpreadElement (
310
+ ts . factory . createParenthesizedExpression (
311
+ ts . factory . createBinaryExpression (
312
+ ts . factory . createIdentifier ( "mutationKey" ) ,
313
+ ts . factory . createToken ( ts . SyntaxKind . QuestionQuestionToken ) ,
314
+ ts . factory . createArrayLiteralExpression ( ) ,
315
+ ) ,
316
+ ) ,
317
+ ) ,
318
+ ] ,
319
+ false ,
320
+ ) ;
321
+ }
322
+
323
+ export function getRequestParamFromMethod (
324
+ method : VariableDeclaration ,
325
+ pageParam ?: string ,
326
+ modelNames : string [ ] = [ ] ,
327
+ ) {
328
+ if ( ! getVariableArrowFunctionParameters ( method ) . length ) {
329
+ return null ;
330
+ }
331
+ const methodName = getNameFromVariable ( method ) ;
332
+
333
+ const params = getVariableArrowFunctionParameters ( method ) . flatMap ( ( param ) => {
334
+ const paramNodes = extractPropertiesFromObjectParam ( param ) ;
335
+
336
+ return paramNodes
337
+ . filter ( ( p ) => p . name !== pageParam )
338
+ . map ( ( refParam ) => ( {
339
+ name : refParam . name ,
340
+ // TODO: Client<Request, Response, unknown, RequestOptions> -> Client<Request, Response, unknown>
341
+ typeName : getShortType ( refParam . type ?. getText ( ) ?? "" ) ,
342
+ optional : refParam . optional ,
343
+ } ) ) ;
344
+ } ) ;
345
+
346
+ const areAllPropertiesOptional = params . every ( ( param ) => param . optional ) ;
347
+
348
+ return ts . factory . createParameterDeclaration (
349
+ undefined ,
350
+ undefined ,
351
+ ts . factory . createIdentifier ( "clientOptions" ) ,
352
+ undefined ,
353
+ ts . factory . createTypeReferenceNode ( ts . factory . createIdentifier ( "Options" ) , [
354
+ ts . factory . createTypeReferenceNode (
355
+ modelNames . includes ( `${ capitalizeFirstLetter ( methodName ) } Data` )
356
+ ? `${ capitalizeFirstLetter ( methodName ) } Data`
357
+ : "unknown" ,
358
+ ) ,
359
+ ts . factory . createTypeReferenceNode ( ts . factory . createIdentifier ( "true" ) ) ,
360
+ ] ) ,
361
+ // if all params are optional, we create an empty object literal
362
+ // so the hook can be called without any parameters
363
+ areAllPropertiesOptional
364
+ ? ts . factory . createObjectLiteralExpression ( )
365
+ : undefined ,
366
+ ) ;
367
+ }
0 commit comments