wasm-ast-types 0.11.3 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. package/main/client/test/ts-client.issue-71.test.js +103 -0
  2. package/main/context/context.js +2 -1
  3. package/main/utils/types.js +20 -7
  4. package/module/client/test/ts-client.issue-71.test.js +21 -0
  5. package/module/context/context.js +2 -1
  6. package/module/utils/types.js +20 -7
  7. package/package.json +5 -3
  8. package/src/client/client.ts +665 -0
  9. package/src/client/index.ts +1 -0
  10. package/src/client/test/__snapshots__/ts-client.account-nfts.spec.ts.snap +497 -0
  11. package/src/client/test/__snapshots__/ts-client.arrays-ref.spec.ts.snap +452 -0
  12. package/src/client/test/__snapshots__/ts-client.arrays.spec.ts.snap +101 -0
  13. package/src/client/test/__snapshots__/ts-client.cw-named-groups.test.ts.snap +141 -0
  14. package/src/client/test/__snapshots__/ts-client.cw-proposal-single.test.ts.snap +341 -0
  15. package/src/client/test/__snapshots__/ts-client.empty-enums.spec.ts.snap +20 -0
  16. package/src/client/test/__snapshots__/ts-client.issue-71.test.ts.snap +432 -0
  17. package/src/client/test/__snapshots__/ts-client.issues.test.ts.snap +984 -0
  18. package/src/client/test/__snapshots__/ts-client.sg721.spec.ts.snap +350 -0
  19. package/src/client/test/__snapshots__/ts-client.spec.ts.snap +723 -0
  20. package/src/client/test/__snapshots__/ts-client.vectis.spec.ts.snap +337 -0
  21. package/src/client/test/ts-client.account-nfts.spec.ts +55 -0
  22. package/src/client/test/ts-client.arrays-ref.spec.ts +48 -0
  23. package/src/client/test/ts-client.arrays.spec.ts +58 -0
  24. package/src/client/test/ts-client.cw-named-groups.test.ts +48 -0
  25. package/src/client/test/ts-client.cw-proposal-single.test.ts +50 -0
  26. package/src/client/test/ts-client.empty-enums.spec.ts +28 -0
  27. package/src/client/test/ts-client.issue-71.test.ts +51 -0
  28. package/src/client/test/ts-client.issues.test.ts +52 -0
  29. package/src/client/test/ts-client.sg721.spec.ts +46 -0
  30. package/src/client/test/ts-client.spec.ts +166 -0
  31. package/src/client/test/ts-client.vectis.spec.ts +97 -0
  32. package/src/context/context.ts +134 -0
  33. package/src/context/imports.ts +126 -0
  34. package/src/context/index.ts +2 -0
  35. package/src/index.ts +7 -0
  36. package/src/message-composer/__snapshots__/message-composer.spec.ts.snap +271 -0
  37. package/src/message-composer/index.ts +1 -0
  38. package/src/message-composer/message-composer.spec.ts +25 -0
  39. package/src/message-composer/message-composer.ts +305 -0
  40. package/src/react-query/__snapshots__/react-query.spec.ts.snap +913 -0
  41. package/src/react-query/index.ts +1 -0
  42. package/src/react-query/react-query.spec.ts +75 -0
  43. package/src/react-query/react-query.ts +913 -0
  44. package/src/recoil/__snapshots__/recoil.spec.ts.snap +203 -0
  45. package/src/recoil/index.ts +1 -0
  46. package/src/recoil/recoil.spec.ts +38 -0
  47. package/src/recoil/recoil.ts +307 -0
  48. package/src/types.ts +44 -0
  49. package/src/utils/__snapshots__/babel.spec.ts.snap +75 -0
  50. package/src/utils/babel.spec.ts +511 -0
  51. package/src/utils/babel.ts +315 -0
  52. package/src/utils/index.ts +2 -0
  53. package/src/utils/types.ts +459 -0
  54. package/types/client/client.d.ts +1 -1
  55. package/types/context/context.d.ts +1 -0
@@ -0,0 +1,913 @@
1
+ import type { Expression } from '@babel/types';
2
+ import * as t from '@babel/types';
3
+ import { camel, pascal } from 'case';
4
+ import { ExecuteMsg, QueryMsg } from '../types';
5
+ import { callExpression, getMessageProperties, identifier, tsObjectPattern, tsPropertySignature } from '../utils';
6
+ import {
7
+ omitTypeReference,
8
+ optionalConditionalExpression,
9
+ propertySignature,
10
+ shorthandProperty
11
+ } from '../utils/babel';
12
+ import { getParamsTypeAnnotation, getPropertyType, getResponseType } from '../utils/types';
13
+ import { ReactQueryOptions, RenderContext } from '../context';
14
+ import { JSONSchema } from '../types';
15
+ import { FIXED_EXECUTE_PARAMS } from '../client';
16
+
17
+ interface ReactQueryHookQuery {
18
+ context: RenderContext,
19
+ hookName: string;
20
+ hookParamsTypeName: string;
21
+ hookKeyName: string;
22
+ queryKeysName: string
23
+ responseType: string;
24
+ methodName: string;
25
+ jsonschema: any;
26
+ }
27
+
28
+ interface ReactQueryHooks {
29
+ context: RenderContext;
30
+ queryMsg: QueryMsg;
31
+ contractName: string;
32
+ QueryClient: string;
33
+ }
34
+
35
+ export const createReactQueryHooks = ({
36
+ context,
37
+ queryMsg,
38
+ contractName,
39
+ QueryClient
40
+ }: ReactQueryHooks) => {
41
+ const options = context.options.reactQuery;
42
+
43
+ const genericQueryInterfaceName = `${pascal(contractName)}ReactQuery`;
44
+ const underscoreNames: string[] = getMessageProperties(queryMsg).map((schema) => (Object.keys(schema.properties)[0]))
45
+
46
+ const body = []
47
+
48
+ const queryKeysName = `${camel(contractName)}QueryKeys`
49
+ if (options.queryKeys) {
50
+ body.push(
51
+ createReactQueryKeys({
52
+ context,
53
+ queryKeysName,
54
+ camelContractName: camel(contractName),
55
+ underscoreNames,
56
+ }))
57
+ }
58
+
59
+ body.push(
60
+ createReactQueryHookGenericInterface({
61
+ context,
62
+ QueryClient,
63
+ genericQueryInterfaceName,
64
+ }))
65
+
66
+ body.push(...getMessageProperties(queryMsg)
67
+ .reduce((m, schema) => {
68
+ // list_voters
69
+ const underscoreName = Object.keys(schema.properties)[0];
70
+ // listVoters
71
+ const methodName = camel(underscoreName);
72
+ // Cw3FlexMultisigListVotersQuery
73
+ const hookParamsTypeName = `${pascal(contractName)}${pascal(methodName)}Query`;
74
+ // useCw3FlexMultisigListVotersQuery
75
+ const hookName = `use${hookParamsTypeName}`;
76
+ // listVotersResponse
77
+ const responseType = getResponseType(context, underscoreName);
78
+ // cw3FlexMultisigListVoters
79
+ const getterKey = camel(`${contractName}${pascal(methodName)}`);
80
+ const jsonschema = schema.properties[underscoreName];
81
+ return [
82
+ createReactQueryHookInterface({
83
+ context,
84
+ hookParamsTypeName,
85
+ responseType,
86
+ queryInterfaceName: genericQueryInterfaceName,
87
+ QueryClient,
88
+ jsonschema,
89
+ }),
90
+ createReactQueryHook({
91
+ context,
92
+ methodName,
93
+ hookName,
94
+ hookParamsTypeName,
95
+ queryKeysName,
96
+ responseType,
97
+ hookKeyName: getterKey,
98
+ jsonschema
99
+ }),
100
+ ...m,
101
+ ]
102
+ }, [])
103
+ );
104
+
105
+ return body
106
+ };
107
+
108
+
109
+ export const createReactQueryHook = ({
110
+ context,
111
+ hookName,
112
+ hookParamsTypeName,
113
+ responseType,
114
+ hookKeyName,
115
+ queryKeysName,
116
+ methodName,
117
+ jsonschema
118
+ }: ReactQueryHookQuery) => {
119
+
120
+ context.addUtil('useQuery');
121
+ context.addUtil('UseQueryOptions');
122
+
123
+ const options = context.options.reactQuery;
124
+ const keys = Object.keys(jsonschema.properties ?? {});
125
+ let args = [];
126
+ if (keys.length) {
127
+ args = [
128
+ t.objectExpression([
129
+ ...keys.map(prop => {
130
+ return t.objectProperty(
131
+ t.identifier(camel(prop)),
132
+ t.memberExpression(
133
+ t.identifier('args'),
134
+ t.identifier(camel(prop))
135
+ )
136
+ )
137
+ })
138
+ ])
139
+ ]
140
+ }
141
+
142
+ let props = ['client', 'options'];
143
+ if (keys.length) {
144
+ props = ['client', 'args', 'options'];
145
+ }
146
+
147
+ const selectResponseGenericTypeName = 'TData';
148
+
149
+ const queryFunctionDeclaration =
150
+ t.functionDeclaration(
151
+ t.identifier(hookName),
152
+ [
153
+ tsObjectPattern(
154
+ [
155
+ ...props.map(prop => {
156
+ return t.objectProperty(
157
+ t.identifier(prop),
158
+ t.identifier(prop),
159
+ false,
160
+ true
161
+ )
162
+ })
163
+ ],
164
+ t.tsTypeAnnotation(t.tsTypeReference(
165
+ t.identifier(hookParamsTypeName),
166
+ t.tsTypeParameterInstantiation([
167
+ t.tsTypeReference(t.identifier(selectResponseGenericTypeName))
168
+ ])
169
+ ))
170
+ )
171
+ ],
172
+ t.blockStatement(
173
+ [
174
+
175
+ t.returnStatement(
176
+ callExpression(
177
+ t.identifier('useQuery'),
178
+ [
179
+ generateUseQueryQueryKey({ hookKeyName, queryKeysName, methodName, props, options }),
180
+ t.arrowFunctionExpression(
181
+ [],
182
+ optionalConditionalExpression(
183
+ t.identifier('client'),
184
+ t.callExpression(
185
+ t.memberExpression(
186
+ t.identifier('client'),
187
+ t.identifier(methodName)
188
+ ),
189
+ args
190
+ ),
191
+ t.callExpression(
192
+ t.memberExpression(
193
+ t.identifier('Promise'),
194
+ t.identifier('reject'),
195
+ ),
196
+ [
197
+ t.newExpression(
198
+ t.identifier('Error'),
199
+ [
200
+ t.stringLiteral('Invalid client')
201
+ ]
202
+ )
203
+ ]
204
+ ),
205
+ options.optionalClient
206
+ ),
207
+ false
208
+ ),
209
+ options.optionalClient
210
+ ? t.objectExpression([
211
+ t.spreadElement(t.identifier('options')),
212
+ t.objectProperty(
213
+ t.identifier('enabled'),
214
+ t.logicalExpression(
215
+ '&&',
216
+ t.unaryExpression(
217
+ '!',
218
+ t.unaryExpression('!', t.identifier('client'))
219
+ ),
220
+ t.conditionalExpression(
221
+ // explicitly check for undefined
222
+ t.binaryExpression(
223
+ '!=',
224
+ t.optionalMemberExpression(
225
+ t.identifier('options'),
226
+ t.identifier('enabled'),
227
+ false,
228
+ true
229
+ ),
230
+ t.identifier('undefined')
231
+ ),
232
+ t.memberExpression(
233
+ t.identifier('options'),
234
+ t.identifier('enabled')
235
+ ),
236
+ t.booleanLiteral(true)
237
+ )
238
+
239
+ )),
240
+ ])
241
+ : t.identifier('options'),
242
+ ],
243
+ t.tsTypeParameterInstantiation(
244
+ [
245
+ t.tsTypeReference(
246
+ t.identifier(responseType)
247
+ ),
248
+ t.tsTypeReference(
249
+ t.identifier('Error')
250
+ ),
251
+ t.tsTypeReference(
252
+ t.identifier(selectResponseGenericTypeName)
253
+ )
254
+ ]
255
+ )
256
+ )
257
+ )
258
+
259
+ ]
260
+ ),
261
+ )
262
+
263
+ // Add the TData type parameters
264
+ queryFunctionDeclaration.typeParameters = t.tsTypeParameterDeclaration([
265
+ t.tsTypeParameter(
266
+ undefined,
267
+ t.tSTypeReference(t.identifier(responseType)),
268
+ selectResponseGenericTypeName
269
+ )
270
+ ])
271
+
272
+ return t.exportNamedDeclaration(queryFunctionDeclaration)
273
+
274
+ };
275
+
276
+ interface ReactQueryMutationHookInterface {
277
+ context: RenderContext;
278
+ ExecuteClient: string;
279
+ mutationHookParamsTypeName: string;
280
+ jsonschema: JSONSchema;
281
+ useMutationTypeParameter: t.TSTypeParameterInstantiation;
282
+ }
283
+
284
+ /**
285
+ * Example:
286
+ ```
287
+ export interface Cw4UpdateMembersMutation {
288
+ client: Cw4GroupClient
289
+ args: {
290
+ tokenId: string
291
+ remove: string[]
292
+ }
293
+ options?: Omit<
294
+ UseMutationOptions<ExecuteResult, Error, Pick<Cw4UpdateMembersMutation, 'args'>>,
295
+ 'mutationFn'
296
+ >
297
+ }
298
+ ```
299
+ */
300
+ export const createReactQueryMutationArgsInterface = ({
301
+ context,
302
+ ExecuteClient,
303
+ mutationHookParamsTypeName,
304
+ useMutationTypeParameter,
305
+ jsonschema,
306
+ }: ReactQueryMutationHookInterface) => {
307
+
308
+ const typedUseMutationOptions = t.tsTypeReference(
309
+ t.identifier('UseMutationOptions'),
310
+ useMutationTypeParameter
311
+ )
312
+
313
+ const body = [
314
+ tsPropertySignature(
315
+ t.identifier('client'),
316
+ t.tsTypeAnnotation(
317
+ t.tsTypeReference(
318
+ t.identifier(ExecuteClient)
319
+ )
320
+ ),
321
+ false
322
+ ),
323
+ ]
324
+
325
+ const msgType: t.TSTypeAnnotation = getParamsTypeAnnotation(context, jsonschema)
326
+
327
+ if (msgType) {
328
+ body.push(
329
+ t.tsPropertySignature(
330
+ t.identifier('msg'),
331
+ msgType
332
+ ))
333
+ }
334
+
335
+ context.addUtil('StdFee')
336
+ context.addUtil('Coin');
337
+ // fee: number | StdFee | "auto" = "auto", memo?: string, funds?: Coin[]
338
+
339
+ const optionalArgs = t.tsPropertySignature(
340
+ t.identifier('args'),
341
+ t.tsTypeAnnotation(
342
+ // @ts-ignore:next-line
343
+ t.tsTypeLiteral(FIXED_EXECUTE_PARAMS.map(param => propertySignature(
344
+ param.name,
345
+ // @ts-ignore:next-line
346
+ param.typeAnnotation,
347
+ param.optional
348
+ )))
349
+ )
350
+ )
351
+
352
+ optionalArgs.optional = true
353
+
354
+ body.push(optionalArgs)
355
+
356
+
357
+ return t.exportNamedDeclaration(t.tsInterfaceDeclaration(
358
+ t.identifier(mutationHookParamsTypeName),
359
+ null,
360
+ [],
361
+ t.tsInterfaceBody(
362
+ body
363
+ )
364
+ ))
365
+ };
366
+
367
+
368
+ interface ReactQueryMutationHooks {
369
+ context: RenderContext;
370
+ execMsg: ExecuteMsg;
371
+ contractName: string;
372
+ ExecuteClient: string;
373
+ }
374
+
375
+ export const createReactQueryMutationHooks = ({
376
+ context,
377
+ execMsg,
378
+ contractName,
379
+ ExecuteClient
380
+ }: ReactQueryMutationHooks) => {
381
+ // merge the user options with the defaults
382
+ return getMessageProperties(execMsg)
383
+ .reduce((m, schema) => {
384
+ // update_members
385
+ const execMethodUnderscoreName = Object.keys(schema.properties)[0];
386
+ // updateMembers
387
+ const execMethodName = camel(execMethodUnderscoreName);
388
+ // Cw20UpdateMembersMutation
389
+ const mutationHookParamsTypeName = `${pascal(contractName)}${pascal(execMethodName)}Mutation`;
390
+ // useCw20UpdateMembersMutation
391
+ const mutationHookName = `use${mutationHookParamsTypeName}`;
392
+
393
+ const jsonschema = schema.properties[execMethodUnderscoreName];
394
+
395
+ const properties = jsonschema.properties ?? {};
396
+
397
+ // TODO: there should be a better way to do this
398
+ const hasMsg = !!(Object.keys(properties)?.length || jsonschema?.$ref)
399
+
400
+ // <ExecuteResult, Error, Cw4UpdateMembersMutation>
401
+ const useMutationTypeParameter = generateMutationTypeParameter(
402
+ context,
403
+ mutationHookParamsTypeName
404
+ );
405
+
406
+
407
+ return [
408
+ createReactQueryMutationArgsInterface({
409
+ context,
410
+ mutationHookParamsTypeName,
411
+ ExecuteClient,
412
+ jsonschema,
413
+ useMutationTypeParameter
414
+ }),
415
+ createReactQueryMutationHook({
416
+ context,
417
+ execMethodName,
418
+ mutationHookName,
419
+ mutationHookParamsTypeName,
420
+ hasMsg,
421
+ useMutationTypeParameter,
422
+ }),
423
+ ...m,
424
+ ]
425
+ }, []);
426
+ };
427
+
428
+ /**
429
+ * Generates the mutation type parameter. If args exist, we use a pick. If not, we just return the params type.
430
+ */
431
+ const generateMutationTypeParameter = (
432
+ context: RenderContext,
433
+ mutationHookParamsTypeName: string
434
+ ) => {
435
+
436
+ context.addUtil('ExecuteResult');
437
+
438
+ return t.tsTypeParameterInstantiation([
439
+ // Data
440
+ t.tSTypeReference(
441
+ t.identifier('ExecuteResult')
442
+ ),
443
+ // Error
444
+ t.tsTypeReference(
445
+ t.identifier('Error')
446
+ ),
447
+ // Variables
448
+ t.tsTypeReference(
449
+ t.identifier(mutationHookParamsTypeName)
450
+ )
451
+ ]);
452
+ }
453
+
454
+
455
+ interface ReactQueryMutationHook {
456
+ context: RenderContext;
457
+ mutationHookName: string;
458
+ mutationHookParamsTypeName: string;
459
+ execMethodName: string;
460
+ useMutationTypeParameter: t.TSTypeParameterInstantiation;
461
+ hasMsg: boolean;
462
+ }
463
+
464
+ /**
465
+ *
466
+ * Example:
467
+ ```
468
+ export const useCw4UpdateMembersMutation = ({ client, options }: Omit<Cw4UpdateMembersMutation, 'args'>) =>
469
+ useMutation<ExecuteResult, Error, Pick<Cw4UpdateMembersMutation, 'args'>>(
470
+ ({ args }) => client.updateMembers(args),
471
+ options
472
+ )
473
+ ```
474
+ */
475
+ export const createReactQueryMutationHook = ({
476
+ context,
477
+ mutationHookName,
478
+ mutationHookParamsTypeName,
479
+ execMethodName,
480
+ useMutationTypeParameter,
481
+ hasMsg,
482
+ }: ReactQueryMutationHook) => {
483
+
484
+ context.addUtil('useMutation');
485
+ context.addUtil('UseMutationOptions');
486
+
487
+ const useMutationFunctionArgs = [shorthandProperty('client')]
488
+ if (hasMsg) useMutationFunctionArgs.push(shorthandProperty('msg'))
489
+ useMutationFunctionArgs.push(
490
+ t.objectProperty(
491
+ t.identifier('args'),
492
+ t.assignmentPattern(
493
+ t.objectPattern(FIXED_EXECUTE_PARAMS.map(param => shorthandProperty(param.name))),
494
+ t.objectExpression([])
495
+ )
496
+ )
497
+ )
498
+
499
+ return t.exportNamedDeclaration(
500
+ t.functionDeclaration(
501
+ t.identifier(mutationHookName),
502
+ [
503
+ identifier('options', t.tsTypeAnnotation(
504
+ omitTypeReference(
505
+ t.tsTypeReference(
506
+ t.identifier('UseMutationOptions'),
507
+ useMutationTypeParameter
508
+ ),
509
+ 'mutationFn'
510
+ )
511
+ ), true)
512
+ ],
513
+ t.blockStatement(
514
+ [
515
+ t.returnStatement(
516
+ callExpression(
517
+ t.identifier('useMutation'),
518
+ [
519
+ t.arrowFunctionExpression(
520
+ [t.objectPattern(useMutationFunctionArgs)],
521
+ t.callExpression(
522
+ t.memberExpression(
523
+ t.identifier('client'),
524
+ t.identifier(execMethodName)
525
+ ),
526
+ (hasMsg
527
+ ? [t.identifier('msg')]
528
+ : []
529
+ )
530
+ .concat(FIXED_EXECUTE_PARAMS.map(param => t.identifier(param.name)))
531
+ ),
532
+ false // not async
533
+ ),
534
+ t.identifier('options'),
535
+ ],
536
+ useMutationTypeParameter
537
+ )
538
+ )
539
+
540
+ ]
541
+ ),
542
+ )
543
+ )
544
+
545
+ };
546
+
547
+ function createReactQueryKeys({
548
+ context,
549
+ queryKeysName,
550
+ camelContractName,
551
+ underscoreNames
552
+ }: {
553
+ context: RenderContext;
554
+ queryKeysName: string,
555
+ camelContractName: string;
556
+ underscoreNames: string[];
557
+ }) {
558
+ const options = context.options.reactQuery
559
+
560
+ const contractAddressTypeAnnotation = t.tsTypeAnnotation(
561
+ options.optionalClient
562
+ ? t.tsUnionType([
563
+ t.tsStringKeyword(),
564
+ t.tsUndefinedKeyword()
565
+ ])
566
+ : t.tSStringKeyword()
567
+ )
568
+
569
+ return t.exportNamedDeclaration(
570
+ t.variableDeclaration('const', [
571
+ t.variableDeclarator(
572
+ t.identifier(queryKeysName),
573
+ t.objectExpression([
574
+ // 1: contract
575
+ t.objectProperty(
576
+ t.identifier('contract'),
577
+ t.tSAsExpression(
578
+ t.arrayExpression([
579
+ t.objectExpression([
580
+ t.objectProperty(
581
+ t.identifier('contract'),
582
+ t.stringLiteral(camelContractName)
583
+ )
584
+ ])
585
+ ]),
586
+ t.tSTypeReference(t.identifier('const'))
587
+ )
588
+ ),
589
+ // 2: address
590
+ t.objectProperty(
591
+ t.identifier('address'),
592
+ t.arrowFunctionExpression(
593
+ [
594
+ identifier(
595
+ 'contractAddress',
596
+ contractAddressTypeAnnotation
597
+ )
598
+ ],
599
+ t.tSAsExpression(
600
+ t.arrayExpression([
601
+ t.objectExpression([
602
+ // 1
603
+ t.spreadElement(
604
+ t.memberExpression(
605
+ t.memberExpression(
606
+ t.identifier(queryKeysName),
607
+ t.identifier('contract')
608
+ ),
609
+ t.numericLiteral(0),
610
+ true // computed
611
+ )
612
+ ),
613
+ t.objectProperty(
614
+ t.identifier('address'),
615
+ t.identifier('contractAddress')
616
+ )
617
+ ])
618
+ ]),
619
+ t.tSTypeReference(t.identifier('const'))
620
+ )
621
+ )
622
+ ),
623
+ // 3: methods
624
+ ...underscoreNames.map((underscoreMethodName) =>
625
+ t.objectProperty(
626
+ // key id is the camel method name
627
+ t.identifier(camel(underscoreMethodName)),
628
+ t.arrowFunctionExpression(
629
+ [
630
+ identifier(
631
+ 'contractAddress',
632
+ contractAddressTypeAnnotation
633
+ ),
634
+ identifier(
635
+ 'args',
636
+ // Record<string, unknown>
637
+ t.tSTypeAnnotation(
638
+ t.tsTypeReference(
639
+ t.identifier('Record'),
640
+ t.tsTypeParameterInstantiation([
641
+ t.tsStringKeyword(),
642
+ t.tsUnknownKeyword()
643
+ ])
644
+ )
645
+ ),
646
+ true // optional
647
+ )
648
+ ],
649
+ t.tSAsExpression(
650
+ t.arrayExpression([
651
+ t.objectExpression([
652
+ //...cw3FlexMultisigQueryKeys.address(contractAddress)[0]
653
+ t.spreadElement(
654
+ t.memberExpression(
655
+ t.callExpression(
656
+ t.memberExpression(
657
+ t.identifier(queryKeysName),
658
+ t.identifier('address')
659
+ ),
660
+ [t.identifier('contractAddress')]
661
+ ),
662
+ t.numericLiteral(0),
663
+ true // computed
664
+ )
665
+ ),
666
+ // method: list_voters
667
+ t.objectProperty(
668
+ t.identifier('method'),
669
+ t.stringLiteral(underscoreMethodName)
670
+ ),
671
+ // args
672
+ shorthandProperty('args')
673
+ ])
674
+ ]),
675
+ t.tSTypeReference(t.identifier('const'))
676
+ )
677
+ )
678
+ )
679
+ )
680
+ ])
681
+ )
682
+ ])
683
+ )
684
+ }
685
+
686
+ interface ReactQueryHookGenericInterface {
687
+ context: RenderContext,
688
+ QueryClient: string,
689
+ genericQueryInterfaceName: string
690
+ }
691
+
692
+ function createReactQueryHookGenericInterface({
693
+ context,
694
+ QueryClient,
695
+ genericQueryInterfaceName
696
+ }: ReactQueryHookGenericInterface) {
697
+
698
+ const options = context.options.reactQuery;
699
+
700
+ const genericResponseTypeName = 'TResponse'
701
+ const genericSelectResponseTypeName = 'TData'
702
+
703
+ context.addUtil('UseQueryOptions');
704
+
705
+ // UseQueryOptions<TResponse, Error, TData>,
706
+ const typedUseQueryOptions = t.tsTypeReference(
707
+ t.identifier('UseQueryOptions'),
708
+ t.tsTypeParameterInstantiation(
709
+ [
710
+ t.tsTypeReference(
711
+ t.identifier(genericResponseTypeName)
712
+ ),
713
+ t.tsTypeReference(t.identifier('Error')),
714
+ t.tsTypeReference(
715
+ t.identifier(genericSelectResponseTypeName)
716
+ )
717
+ ])
718
+ )
719
+
720
+ const body = [
721
+ tsPropertySignature(
722
+ t.identifier('client'),
723
+ t.tsTypeAnnotation(
724
+ options.optionalClient
725
+ ? t.tsUnionType([
726
+ t.tsTypeReference(
727
+ t.identifier(QueryClient)
728
+ ),
729
+ t.tsUndefinedKeyword()
730
+ ])
731
+ : t.tsTypeReference(
732
+ t.identifier(QueryClient)
733
+ )
734
+ ),
735
+ false
736
+ ),
737
+ tsPropertySignature(
738
+ t.identifier('options'),
739
+ t.tsTypeAnnotation(
740
+ options.version === 'v4'
741
+ ? t.tSIntersectionType([
742
+ omitTypeReference(typedUseQueryOptions, "'queryKey' | 'queryFn' | 'initialData'"),
743
+ t.tSTypeLiteral([
744
+ t.tsPropertySignature(
745
+ t.identifier('initialData?'),
746
+ t.tsTypeAnnotation(
747
+ t.tsUndefinedKeyword()
748
+ )
749
+ )
750
+ ])
751
+ ])
752
+ : typedUseQueryOptions
753
+ ),
754
+ true
755
+ )
756
+ ];
757
+
758
+ return t.exportNamedDeclaration(
759
+ t.tsInterfaceDeclaration(
760
+ t.identifier(genericQueryInterfaceName),
761
+ t.tsTypeParameterDeclaration([
762
+ // 1: TResponse
763
+ t.tsTypeParameter(undefined, undefined, genericResponseTypeName),
764
+ // 2: TData
765
+ t.tsTypeParameter(
766
+ undefined,
767
+ t.tSTypeReference(t.identifier(genericResponseTypeName)),
768
+ genericSelectResponseTypeName
769
+ )
770
+ ]),
771
+ [],
772
+ t.tSInterfaceBody(body)
773
+ )
774
+ )
775
+ }
776
+
777
+ interface ReactQueryHookQueryInterface {
778
+ context: RenderContext,
779
+ QueryClient: string;
780
+ hookParamsTypeName: string;
781
+ queryInterfaceName: string
782
+ responseType: string;
783
+ jsonschema: any;
784
+ }
785
+
786
+ export const createReactQueryHookInterface = ({
787
+ context,
788
+ QueryClient,
789
+ hookParamsTypeName,
790
+ queryInterfaceName,
791
+ responseType,
792
+ jsonschema
793
+ }: ReactQueryHookQueryInterface) => {
794
+ // merge the user options with the defaults
795
+ const options = context.options.reactQuery;
796
+
797
+ const body = []
798
+
799
+ const props = getProps(context, jsonschema);
800
+ if (props.length) {
801
+ body.push(t.tsPropertySignature(
802
+ t.identifier('args'),
803
+ t.tsTypeAnnotation(
804
+ // @ts-ignore:next-line
805
+ t.tsTypeLiteral(props)
806
+ )
807
+ ))
808
+ }
809
+
810
+
811
+ return t.exportNamedDeclaration(
812
+ t.tsInterfaceDeclaration(
813
+ t.identifier(hookParamsTypeName),
814
+ t.tsTypeParameterDeclaration([
815
+ t.tSTypeParameter(undefined, undefined, 'TData')
816
+ ]),
817
+ [
818
+ t.tSExpressionWithTypeArguments(
819
+ t.identifier(queryInterfaceName),
820
+ t.tsTypeParameterInstantiation([
821
+ // 1: response
822
+ t.tsTypeReference(t.identifier(responseType)),
823
+ // 2: select generic
824
+ t.tSTypeReference(t.identifier('TData'))
825
+ ])
826
+ )
827
+ ],
828
+ t.tsInterfaceBody(
829
+ body
830
+ )
831
+ )
832
+ )
833
+ };
834
+
835
+ const getProps = (
836
+ context: RenderContext,
837
+ jsonschema: JSONSchema
838
+ ) => {
839
+ const keys = Object.keys(jsonschema.properties ?? {});
840
+ if (!keys.length) return [];
841
+
842
+ return keys.map(prop => {
843
+ const { type, optional } = getPropertyType(context, jsonschema, prop);
844
+ return propertySignature(
845
+ context.options.reactQuery.camelize ? camel(prop) : prop,
846
+ t.tsTypeAnnotation(
847
+ type
848
+ ),
849
+ optional
850
+ )
851
+ });
852
+ }
853
+
854
+ interface GenerateUseQueryQueryKeyParams {
855
+ hookKeyName: string;
856
+ queryKeysName: string;
857
+ methodName: string;
858
+ props: string[];
859
+ options: ReactQueryOptions;
860
+ }
861
+
862
+ const generateUseQueryQueryKey = ({
863
+ hookKeyName,
864
+ queryKeysName,
865
+ methodName,
866
+ props,
867
+ options,
868
+ }: GenerateUseQueryQueryKeyParams): t.ArrayExpression | t.CallExpression => {
869
+ const { optionalClient, queryKeys } = options
870
+
871
+ const hasArgs = props.includes('args')
872
+
873
+ const contractAddressExpression =
874
+ t.optionalMemberExpression(
875
+ t.identifier('client'),
876
+ t.identifier('contractAddress'),
877
+ false,
878
+ optionalClient
879
+ )
880
+
881
+ if (queryKeys) {
882
+
883
+ const callArgs: Array<Expression> = [contractAddressExpression]
884
+
885
+ if (hasArgs) callArgs.push(t.identifier('args'))
886
+
887
+ return t.callExpression(
888
+ t.memberExpression(
889
+ t.identifier(queryKeysName),
890
+ t.identifier(camel(methodName))
891
+ ),
892
+ callArgs
893
+ )
894
+ }
895
+
896
+ const queryKey: Array<Expression> = [
897
+ t.stringLiteral(hookKeyName),
898
+ contractAddressExpression
899
+ ];
900
+
901
+ if (hasArgs) {
902
+ queryKey.push(t.callExpression(
903
+ t.memberExpression(
904
+ t.identifier('JSON'),
905
+ t.identifier('stringify')
906
+ ),
907
+ [
908
+ t.identifier('args')
909
+ ]
910
+ ))
911
+ }
912
+ return t.arrayExpression(queryKey)
913
+ }