react-query-lightbase-codegen 0.0.21 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import program from 'commander';
|
|
3
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
4
|
+
import { join, parse } from 'path';
|
|
5
|
+
import importOpenApi from '../scripts/import-open-api';
|
|
6
|
+
const log = console.log; // tslint:disable-line:no-console
|
|
7
|
+
program.option('-o, --output [value]', 'output file destination');
|
|
8
|
+
program.option('-f, --file [value]', 'input file (yaml or json openapi specs)');
|
|
9
|
+
program.parse(process.argv);
|
|
10
|
+
const createSuccessMessage = (backend) => chalk.green(`${backend ? `[${backend}] ` : ''}🎉 Your OpenAPI spec has been converted into react query hooks`);
|
|
11
|
+
const successWithoutOutputMessage = chalk.yellow('Success! No output path specified; printed to standard output.');
|
|
12
|
+
const importSpecs = async (options) => {
|
|
13
|
+
if (!options.file) {
|
|
14
|
+
throw new Error("You need to provide an input specification with `--file`, '--url', or `--github`");
|
|
15
|
+
}
|
|
16
|
+
const data = readFileSync(join(process.cwd(), options.file), 'utf-8');
|
|
17
|
+
const { ext } = parse(options.file);
|
|
18
|
+
const format = ['.yaml', '.yml'].includes(ext.toLowerCase()) ? 'yaml' : 'json';
|
|
19
|
+
return importOpenApi({
|
|
20
|
+
data,
|
|
21
|
+
format,
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
// Use flags as configuration
|
|
25
|
+
importSpecs(program)
|
|
26
|
+
.then((data) => {
|
|
27
|
+
if (program.output) {
|
|
28
|
+
writeFileSync(join(process.cwd(), program.output), data);
|
|
29
|
+
log(createSuccessMessage());
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
log(data);
|
|
33
|
+
log(successWithoutOutputMessage);
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
.catch((err) => {
|
|
37
|
+
log(chalk.red(err));
|
|
38
|
+
process.exit(1);
|
|
39
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import program from 'commander';
|
|
2
|
+
import { readFileSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
const { version } = JSON.parse(readFileSync(join(__dirname, '../../package.json'), 'utf-8'));
|
|
5
|
+
program
|
|
6
|
+
.version(version)
|
|
7
|
+
.command('import [open-api-file]', 'generate react-query hooks from OpenAPI specs')
|
|
8
|
+
.parse(process.argv);
|
|
@@ -341,6 +341,13 @@ const generateRestfulComponent = ({ operation, verb, route, operationIds, parame
|
|
|
341
341
|
}
|
|
342
342
|
}), 'in');
|
|
343
343
|
const headerParams = header.filter((p) => !headerFilters?.includes(p.name));
|
|
344
|
+
let enabled = [];
|
|
345
|
+
[...queryParams, ...pathParams, ...headerParams].forEach((item) => {
|
|
346
|
+
if (item.required) {
|
|
347
|
+
enabled.push(`["${item.name}"]`);
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
const enabledParam = `!!props${enabled.join(' && !!props')}`;
|
|
344
351
|
const paramsTypes = paramsInPath
|
|
345
352
|
.map((p) => {
|
|
346
353
|
try {
|
|
@@ -420,6 +427,7 @@ const generateRestfulComponent = ({ operation, verb, route, operationIds, parame
|
|
|
420
427
|
use${componentName}Query.prefetch = (params: ${componentName}Variables) =>
|
|
421
428
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(params), ()=> use${componentName}Query.fetch(params));
|
|
422
429
|
|
|
430
|
+
use${componentName}Query.cancelQueries = (params: ${componentName}Variables) => queryClient.cancelQueries(use${componentName}Query.queryKey(params))
|
|
423
431
|
use${componentName}Query.invalidate = (params: ${componentName}Variables) =>
|
|
424
432
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey(params));
|
|
425
433
|
|
|
@@ -428,7 +436,7 @@ const generateRestfulComponent = ({ operation, verb, route, operationIds, parame
|
|
|
428
436
|
}
|
|
429
437
|
export function use${componentName}Query<T = ${componentName}Response>({ options = {}, ...props }: ${componentName}QueryProps<T>) {
|
|
430
438
|
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props),
|
|
431
|
-
{ enabled:
|
|
439
|
+
{ enabled: ${enabledParam}, ...options }
|
|
432
440
|
);}
|
|
433
441
|
|
|
434
442
|
type ${componentName}MutationProps<T> = {
|
|
@@ -466,6 +474,7 @@ const generateRestfulComponent = ({ operation, verb, route, operationIds, parame
|
|
|
466
474
|
use${componentName}Query.prefetch = (params: ${componentName}Variables) =>
|
|
467
475
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(params), ()=> use${componentName}Query.fetch(params));
|
|
468
476
|
|
|
477
|
+
use${componentName}Query.cancelQueries = (params: ${componentName}Variables) => queryClient.cancelQueries(use${componentName}Query.queryKey(params))
|
|
469
478
|
use${componentName}Query.invalidate = (params: ${componentName}Variables) =>
|
|
470
479
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey(params));
|
|
471
480
|
|
|
@@ -473,7 +482,8 @@ const generateRestfulComponent = ({ operation, verb, route, operationIds, parame
|
|
|
473
482
|
options?: UseQueryOptions<${componentName}Response, AxiosError, T, any>
|
|
474
483
|
}
|
|
475
484
|
export function use${componentName}Query<T = ${componentName}Response>({ options = {}, ...props }: ${componentName}QueryProps<T>) {
|
|
476
|
-
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props), {
|
|
485
|
+
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props), {
|
|
486
|
+
enabled: ${enabledParam}, ...options }
|
|
477
487
|
);}
|
|
478
488
|
|
|
479
489
|
type ${componentName}MutationProps<T> = {
|
|
@@ -503,6 +513,7 @@ const generateRestfulComponent = ({ operation, verb, route, operationIds, parame
|
|
|
503
513
|
use${componentName}Query.prefetch = () =>
|
|
504
514
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(), ()=> use${componentName}Query.fetch());
|
|
505
515
|
|
|
516
|
+
use${componentName}Query.cancelQueries = () => queryClient.cancelQueries(use${componentName}Query.queryKey())
|
|
506
517
|
use${componentName}Query.invalidate = () =>
|
|
507
518
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey());
|
|
508
519
|
|
|
@@ -549,12 +560,13 @@ const generateRestfulComponent = ({ operation, verb, route, operationIds, parame
|
|
|
549
560
|
use${componentName}Query.prefetch = (params: ${componentName}Variables) =>
|
|
550
561
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(params), ()=> use${componentName}Query.fetch(params));
|
|
551
562
|
|
|
563
|
+
use${componentName}Query.cancelQueries = (params: ${componentName}Variables) => queryClient.cancelQueries(use${componentName}Query.queryKey(params))
|
|
552
564
|
use${componentName}Query.invalidate = (params: ${componentName}Variables) =>
|
|
553
565
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey(params));
|
|
554
566
|
|
|
555
567
|
export function use${componentName}Query<T = ${componentName}Response>({ options = {}, ...props }: ${componentName}Variables & { options?: UseQueryOptions<${componentName}Response, AxiosError, T, any>}) {
|
|
556
568
|
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props),
|
|
557
|
-
{ enabled:
|
|
569
|
+
{ enabled: ${enabledParam}, ...options }
|
|
558
570
|
);}
|
|
559
571
|
|
|
560
572
|
export function use${componentName}Mutation<T = ${componentName}Response>(props?: { options?: UseMutationOptions<${componentName}Response, AxiosError, ${componentName}Variables, T>}) {
|
|
@@ -585,6 +597,7 @@ const generateRestfulComponent = ({ operation, verb, route, operationIds, parame
|
|
|
585
597
|
use${componentName}Query.prefetch = (params: ${componentName}Variables) =>
|
|
586
598
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(params), ()=> use${componentName}Query.fetch(params));
|
|
587
599
|
|
|
600
|
+
use${componentName}Query.cancelQueries = (params: ${componentName}Variables) => queryClient.cancelQueries(use${componentName}Query.queryKey(params))
|
|
588
601
|
use${componentName}Query.invalidate = (params: ${componentName}Variables) =>
|
|
589
602
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey(params));
|
|
590
603
|
|
|
@@ -608,7 +621,9 @@ const generateRestfulComponent = ({ operation, verb, route, operationIds, parame
|
|
|
608
621
|
output += `
|
|
609
622
|
type ${componentName}Response = ${genericsTypes}
|
|
610
623
|
type ${componentName}Variables = {
|
|
611
|
-
body: ${requestBodyComponent}
|
|
624
|
+
body: ${requestBodyComponent}
|
|
625
|
+
${paramsTypes}
|
|
626
|
+
}
|
|
612
627
|
|
|
613
628
|
type ${componentName}QueryProps<T = ${componentName}Response> = ${componentName}Variables & {
|
|
614
629
|
options?: UseQueryOptions<${componentName}Response, AxiosError, T, any>
|
|
@@ -631,12 +646,14 @@ const generateRestfulComponent = ({ operation, verb, route, operationIds, parame
|
|
|
631
646
|
use${componentName}Query.prefetch = (params: ${componentName}Variables) =>
|
|
632
647
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(params), ()=> use${componentName}Query.fetch(params));
|
|
633
648
|
|
|
649
|
+
use${componentName}Query.cancelQueries = (params: ${componentName}Variables) => queryClient.cancelQueries(use${componentName}Query.queryKey(params))
|
|
634
650
|
use${componentName}Query.invalidate = (params: ${componentName}Variables) =>
|
|
635
651
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey(params));
|
|
636
652
|
|
|
637
653
|
|
|
638
654
|
export function use${componentName}Query<T = ${componentName}Response>({ options = {}, ...props }: ${componentName}QueryProps<T>) {
|
|
639
|
-
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props), {
|
|
655
|
+
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props), {
|
|
656
|
+
enabled: ${enabledParam}, ...options }
|
|
640
657
|
);}
|
|
641
658
|
|
|
642
659
|
type ${componentName}MutationProps<T> = {
|
|
@@ -678,14 +695,14 @@ const generateRestfulComponent = ({ operation, verb, route, operationIds, parame
|
|
|
678
695
|
use${componentName}Query.prefetch = (params: ${componentName}Variables) =>
|
|
679
696
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(params), ()=> use${componentName}Query.fetch(params));
|
|
680
697
|
|
|
698
|
+
use${componentName}Query.cancelQueries = (params: ${componentName}Variables) => queryClient.cancelQueries(use${componentName}Query.queryKey(params))
|
|
681
699
|
use${componentName}Query.invalidate = (params: ${componentName}Variables) =>
|
|
682
700
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey(params));
|
|
683
701
|
|
|
684
702
|
|
|
685
703
|
export function use${componentName}Query<T = ${componentName}Response>({ options = {}, ...props }: ${componentName}QueryProps<T>) {
|
|
686
|
-
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props), {
|
|
687
|
-
|
|
688
|
-
.join(' && !!props')}, ...options }
|
|
704
|
+
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props), {
|
|
705
|
+
enabled: ${enabledParam}, ...options }
|
|
689
706
|
);}
|
|
690
707
|
|
|
691
708
|
|
|
@@ -736,6 +753,7 @@ const generateRestfulComponent = ({ operation, verb, route, operationIds, parame
|
|
|
736
753
|
use${componentName}Query.prefetch = (params: ${componentName}Variables) =>
|
|
737
754
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(params), ()=> use${componentName}Query.fetch(params));
|
|
738
755
|
|
|
756
|
+
use${componentName}Query.cancelQueries = (params: ${componentName}Variables) => queryClient.cancelQueries(use${componentName}Query.queryKey(params))
|
|
739
757
|
use${componentName}Query.invalidate = (params: ${componentName}Variables) =>
|
|
740
758
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey(params));
|
|
741
759
|
|
|
@@ -745,7 +763,7 @@ const generateRestfulComponent = ({ operation, verb, route, operationIds, parame
|
|
|
745
763
|
}
|
|
746
764
|
export function use${componentName}Query<T = ${componentName}Response>({ options = {}, ...props }: ${componentName}QueryProps<T>) {
|
|
747
765
|
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props),
|
|
748
|
-
{ enabled:
|
|
766
|
+
{ enabled: ${enabledParam}, ...options }
|
|
749
767
|
);}
|
|
750
768
|
|
|
751
769
|
|
|
@@ -789,7 +807,8 @@ const generateRestfulComponent = ({ operation, verb, route, operationIds, parame
|
|
|
789
807
|
use${componentName}Query.prefetch = (params: ${componentName}Variables) =>
|
|
790
808
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(params), ()=> use${componentName}Query.fetch(params));
|
|
791
809
|
|
|
792
|
-
use${componentName}Query.
|
|
810
|
+
use${componentName}Query.cancelQueries = (params: ${componentName}Variables) => queryClient.cancelQueries(use${componentName}Query.queryKey(params))
|
|
811
|
+
use${componentName}Query.invalidate = (params: ${componentName}Variables) =>
|
|
793
812
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey(params));
|
|
794
813
|
|
|
795
814
|
type ${componentName}QueryProps<T = ${componentName}Response> = ${componentName}Variables & {
|
|
@@ -797,9 +816,7 @@ const generateRestfulComponent = ({ operation, verb, route, operationIds, parame
|
|
|
797
816
|
}
|
|
798
817
|
export function use${componentName}Query<T = ${componentName}Response>({ options = {}, ...props }: ${componentName}QueryProps<T>) {
|
|
799
818
|
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props),
|
|
800
|
-
{
|
|
801
|
-
.map((param) => `["${param.name}"]`)
|
|
802
|
-
.join(' && !!props')}, ...options }
|
|
819
|
+
{ enabled: ${enabledParam}, ...options }
|
|
803
820
|
);}
|
|
804
821
|
|
|
805
822
|
type ${componentName}MutationProps<T> = {
|
|
@@ -840,6 +857,7 @@ const generateRestfulComponent = ({ operation, verb, route, operationIds, parame
|
|
|
840
857
|
use${componentName}Query.prefetch = (params: ${componentName}Variables) =>
|
|
841
858
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(params), ()=> use${componentName}Query.fetch(params));
|
|
842
859
|
|
|
860
|
+
use${componentName}Query.cancelQueries = (params: ${componentName}Variables) => queryClient.cancelQueries(use${componentName}Query.queryKey(params))
|
|
843
861
|
use${componentName}Query.invalidate = (params: ${componentName}Variables) =>
|
|
844
862
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey(params));
|
|
845
863
|
|
|
@@ -847,9 +865,8 @@ const generateRestfulComponent = ({ operation, verb, route, operationIds, parame
|
|
|
847
865
|
options?: UseQueryOptions<${componentName}Response, AxiosError, T, any>
|
|
848
866
|
}
|
|
849
867
|
export function use${componentName}Query<T = ${componentName}Response>({ options = {}, ...body }: ${componentName}QueryProps<T>) {
|
|
850
|
-
return useQuery(use${componentName}Query.queryKey(body), async () => use${componentName}Query.fetch(body),{
|
|
851
|
-
|
|
852
|
-
.join(' && !!props')}, ...options }
|
|
868
|
+
return useQuery(use${componentName}Query.queryKey(body), async () => use${componentName}Query.fetch(body),{
|
|
869
|
+
enabled: ${enabledParam}, ...options }
|
|
853
870
|
);}
|
|
854
871
|
|
|
855
872
|
|
|
@@ -321,6 +321,13 @@ export const generateRestfulComponent = ({ operation, verb, route, operationIds,
|
|
|
321
321
|
}
|
|
322
322
|
}), 'in');
|
|
323
323
|
const headerParams = header.filter((p) => !headerFilters?.includes(p.name));
|
|
324
|
+
let enabled = [];
|
|
325
|
+
[...queryParams, ...pathParams, ...headerParams].forEach((item) => {
|
|
326
|
+
if (item.required) {
|
|
327
|
+
enabled.push(`["${item.name}"]`);
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
const enabledParam = `!!props${enabled.join(' && !!props')}`;
|
|
324
331
|
const paramsTypes = paramsInPath
|
|
325
332
|
.map((p) => {
|
|
326
333
|
try {
|
|
@@ -400,6 +407,7 @@ export const generateRestfulComponent = ({ operation, verb, route, operationIds,
|
|
|
400
407
|
use${componentName}Query.prefetch = (params: ${componentName}Variables) =>
|
|
401
408
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(params), ()=> use${componentName}Query.fetch(params));
|
|
402
409
|
|
|
410
|
+
use${componentName}Query.cancelQueries = (params: ${componentName}Variables) => queryClient.cancelQueries(use${componentName}Query.queryKey(params))
|
|
403
411
|
use${componentName}Query.invalidate = (params: ${componentName}Variables) =>
|
|
404
412
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey(params));
|
|
405
413
|
|
|
@@ -408,7 +416,7 @@ export const generateRestfulComponent = ({ operation, verb, route, operationIds,
|
|
|
408
416
|
}
|
|
409
417
|
export function use${componentName}Query<T = ${componentName}Response>({ options = {}, ...props }: ${componentName}QueryProps<T>) {
|
|
410
418
|
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props),
|
|
411
|
-
{ enabled:
|
|
419
|
+
{ enabled: ${enabledParam}, ...options }
|
|
412
420
|
);}
|
|
413
421
|
|
|
414
422
|
type ${componentName}MutationProps<T> = {
|
|
@@ -446,6 +454,7 @@ export const generateRestfulComponent = ({ operation, verb, route, operationIds,
|
|
|
446
454
|
use${componentName}Query.prefetch = (params: ${componentName}Variables) =>
|
|
447
455
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(params), ()=> use${componentName}Query.fetch(params));
|
|
448
456
|
|
|
457
|
+
use${componentName}Query.cancelQueries = (params: ${componentName}Variables) => queryClient.cancelQueries(use${componentName}Query.queryKey(params))
|
|
449
458
|
use${componentName}Query.invalidate = (params: ${componentName}Variables) =>
|
|
450
459
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey(params));
|
|
451
460
|
|
|
@@ -453,7 +462,8 @@ export const generateRestfulComponent = ({ operation, verb, route, operationIds,
|
|
|
453
462
|
options?: UseQueryOptions<${componentName}Response, AxiosError, T, any>
|
|
454
463
|
}
|
|
455
464
|
export function use${componentName}Query<T = ${componentName}Response>({ options = {}, ...props }: ${componentName}QueryProps<T>) {
|
|
456
|
-
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props), {
|
|
465
|
+
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props), {
|
|
466
|
+
enabled: ${enabledParam}, ...options }
|
|
457
467
|
);}
|
|
458
468
|
|
|
459
469
|
type ${componentName}MutationProps<T> = {
|
|
@@ -483,6 +493,7 @@ export const generateRestfulComponent = ({ operation, verb, route, operationIds,
|
|
|
483
493
|
use${componentName}Query.prefetch = () =>
|
|
484
494
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(), ()=> use${componentName}Query.fetch());
|
|
485
495
|
|
|
496
|
+
use${componentName}Query.cancelQueries = () => queryClient.cancelQueries(use${componentName}Query.queryKey())
|
|
486
497
|
use${componentName}Query.invalidate = () =>
|
|
487
498
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey());
|
|
488
499
|
|
|
@@ -529,12 +540,13 @@ export const generateRestfulComponent = ({ operation, verb, route, operationIds,
|
|
|
529
540
|
use${componentName}Query.prefetch = (params: ${componentName}Variables) =>
|
|
530
541
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(params), ()=> use${componentName}Query.fetch(params));
|
|
531
542
|
|
|
543
|
+
use${componentName}Query.cancelQueries = (params: ${componentName}Variables) => queryClient.cancelQueries(use${componentName}Query.queryKey(params))
|
|
532
544
|
use${componentName}Query.invalidate = (params: ${componentName}Variables) =>
|
|
533
545
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey(params));
|
|
534
546
|
|
|
535
547
|
export function use${componentName}Query<T = ${componentName}Response>({ options = {}, ...props }: ${componentName}Variables & { options?: UseQueryOptions<${componentName}Response, AxiosError, T, any>}) {
|
|
536
548
|
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props),
|
|
537
|
-
{ enabled:
|
|
549
|
+
{ enabled: ${enabledParam}, ...options }
|
|
538
550
|
);}
|
|
539
551
|
|
|
540
552
|
export function use${componentName}Mutation<T = ${componentName}Response>(props?: { options?: UseMutationOptions<${componentName}Response, AxiosError, ${componentName}Variables, T>}) {
|
|
@@ -565,6 +577,7 @@ export const generateRestfulComponent = ({ operation, verb, route, operationIds,
|
|
|
565
577
|
use${componentName}Query.prefetch = (params: ${componentName}Variables) =>
|
|
566
578
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(params), ()=> use${componentName}Query.fetch(params));
|
|
567
579
|
|
|
580
|
+
use${componentName}Query.cancelQueries = (params: ${componentName}Variables) => queryClient.cancelQueries(use${componentName}Query.queryKey(params))
|
|
568
581
|
use${componentName}Query.invalidate = (params: ${componentName}Variables) =>
|
|
569
582
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey(params));
|
|
570
583
|
|
|
@@ -588,7 +601,9 @@ export const generateRestfulComponent = ({ operation, verb, route, operationIds,
|
|
|
588
601
|
output += `
|
|
589
602
|
type ${componentName}Response = ${genericsTypes}
|
|
590
603
|
type ${componentName}Variables = {
|
|
591
|
-
body: ${requestBodyComponent}
|
|
604
|
+
body: ${requestBodyComponent}
|
|
605
|
+
${paramsTypes}
|
|
606
|
+
}
|
|
592
607
|
|
|
593
608
|
type ${componentName}QueryProps<T = ${componentName}Response> = ${componentName}Variables & {
|
|
594
609
|
options?: UseQueryOptions<${componentName}Response, AxiosError, T, any>
|
|
@@ -611,12 +626,14 @@ export const generateRestfulComponent = ({ operation, verb, route, operationIds,
|
|
|
611
626
|
use${componentName}Query.prefetch = (params: ${componentName}Variables) =>
|
|
612
627
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(params), ()=> use${componentName}Query.fetch(params));
|
|
613
628
|
|
|
629
|
+
use${componentName}Query.cancelQueries = (params: ${componentName}Variables) => queryClient.cancelQueries(use${componentName}Query.queryKey(params))
|
|
614
630
|
use${componentName}Query.invalidate = (params: ${componentName}Variables) =>
|
|
615
631
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey(params));
|
|
616
632
|
|
|
617
633
|
|
|
618
634
|
export function use${componentName}Query<T = ${componentName}Response>({ options = {}, ...props }: ${componentName}QueryProps<T>) {
|
|
619
|
-
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props), {
|
|
635
|
+
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props), {
|
|
636
|
+
enabled: ${enabledParam}, ...options }
|
|
620
637
|
);}
|
|
621
638
|
|
|
622
639
|
type ${componentName}MutationProps<T> = {
|
|
@@ -658,14 +675,14 @@ export const generateRestfulComponent = ({ operation, verb, route, operationIds,
|
|
|
658
675
|
use${componentName}Query.prefetch = (params: ${componentName}Variables) =>
|
|
659
676
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(params), ()=> use${componentName}Query.fetch(params));
|
|
660
677
|
|
|
678
|
+
use${componentName}Query.cancelQueries = (params: ${componentName}Variables) => queryClient.cancelQueries(use${componentName}Query.queryKey(params))
|
|
661
679
|
use${componentName}Query.invalidate = (params: ${componentName}Variables) =>
|
|
662
680
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey(params));
|
|
663
681
|
|
|
664
682
|
|
|
665
683
|
export function use${componentName}Query<T = ${componentName}Response>({ options = {}, ...props }: ${componentName}QueryProps<T>) {
|
|
666
|
-
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props), {
|
|
667
|
-
|
|
668
|
-
.join(' && !!props')}, ...options }
|
|
684
|
+
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props), {
|
|
685
|
+
enabled: ${enabledParam}, ...options }
|
|
669
686
|
);}
|
|
670
687
|
|
|
671
688
|
|
|
@@ -716,6 +733,7 @@ export const generateRestfulComponent = ({ operation, verb, route, operationIds,
|
|
|
716
733
|
use${componentName}Query.prefetch = (params: ${componentName}Variables) =>
|
|
717
734
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(params), ()=> use${componentName}Query.fetch(params));
|
|
718
735
|
|
|
736
|
+
use${componentName}Query.cancelQueries = (params: ${componentName}Variables) => queryClient.cancelQueries(use${componentName}Query.queryKey(params))
|
|
719
737
|
use${componentName}Query.invalidate = (params: ${componentName}Variables) =>
|
|
720
738
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey(params));
|
|
721
739
|
|
|
@@ -725,7 +743,7 @@ export const generateRestfulComponent = ({ operation, verb, route, operationIds,
|
|
|
725
743
|
}
|
|
726
744
|
export function use${componentName}Query<T = ${componentName}Response>({ options = {}, ...props }: ${componentName}QueryProps<T>) {
|
|
727
745
|
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props),
|
|
728
|
-
{ enabled:
|
|
746
|
+
{ enabled: ${enabledParam}, ...options }
|
|
729
747
|
);}
|
|
730
748
|
|
|
731
749
|
|
|
@@ -769,7 +787,8 @@ export const generateRestfulComponent = ({ operation, verb, route, operationIds,
|
|
|
769
787
|
use${componentName}Query.prefetch = (params: ${componentName}Variables) =>
|
|
770
788
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(params), ()=> use${componentName}Query.fetch(params));
|
|
771
789
|
|
|
772
|
-
use${componentName}Query.
|
|
790
|
+
use${componentName}Query.cancelQueries = (params: ${componentName}Variables) => queryClient.cancelQueries(use${componentName}Query.queryKey(params))
|
|
791
|
+
use${componentName}Query.invalidate = (params: ${componentName}Variables) =>
|
|
773
792
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey(params));
|
|
774
793
|
|
|
775
794
|
type ${componentName}QueryProps<T = ${componentName}Response> = ${componentName}Variables & {
|
|
@@ -777,9 +796,7 @@ export const generateRestfulComponent = ({ operation, verb, route, operationIds,
|
|
|
777
796
|
}
|
|
778
797
|
export function use${componentName}Query<T = ${componentName}Response>({ options = {}, ...props }: ${componentName}QueryProps<T>) {
|
|
779
798
|
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props),
|
|
780
|
-
{
|
|
781
|
-
.map((param) => `["${param.name}"]`)
|
|
782
|
-
.join(' && !!props')}, ...options }
|
|
799
|
+
{ enabled: ${enabledParam}, ...options }
|
|
783
800
|
);}
|
|
784
801
|
|
|
785
802
|
type ${componentName}MutationProps<T> = {
|
|
@@ -820,6 +837,7 @@ export const generateRestfulComponent = ({ operation, verb, route, operationIds,
|
|
|
820
837
|
use${componentName}Query.prefetch = (params: ${componentName}Variables) =>
|
|
821
838
|
queryClient.prefetchQuery<${componentName}Response>(use${componentName}Query.queryKey(params), ()=> use${componentName}Query.fetch(params));
|
|
822
839
|
|
|
840
|
+
use${componentName}Query.cancelQueries = (params: ${componentName}Variables) => queryClient.cancelQueries(use${componentName}Query.queryKey(params))
|
|
823
841
|
use${componentName}Query.invalidate = (params: ${componentName}Variables) =>
|
|
824
842
|
queryClient.invalidateQueries<${componentName}Response>(use${componentName}Query.queryKey(params));
|
|
825
843
|
|
|
@@ -827,9 +845,8 @@ export const generateRestfulComponent = ({ operation, verb, route, operationIds,
|
|
|
827
845
|
options?: UseQueryOptions<${componentName}Response, AxiosError, T, any>
|
|
828
846
|
}
|
|
829
847
|
export function use${componentName}Query<T = ${componentName}Response>({ options = {}, ...body }: ${componentName}QueryProps<T>) {
|
|
830
|
-
return useQuery(use${componentName}Query.queryKey(body), async () => use${componentName}Query.fetch(body),{
|
|
831
|
-
|
|
832
|
-
.join(' && !!props')}, ...options }
|
|
848
|
+
return useQuery(use${componentName}Query.queryKey(body), async () => use${componentName}Query.fetch(body),{
|
|
849
|
+
enabled: ${enabledParam}, ...options }
|
|
833
850
|
);}
|
|
834
851
|
|
|
835
852
|
|
|
@@ -0,0 +1,605 @@
|
|
|
1
|
+
import { pascal } from 'case';
|
|
2
|
+
import get from 'lodash/get';
|
|
3
|
+
import groupBy from 'lodash/groupBy';
|
|
4
|
+
import isEmpty from 'lodash/isEmpty';
|
|
5
|
+
import set from 'lodash/set';
|
|
6
|
+
import uniq from 'lodash/uniq';
|
|
7
|
+
import swagger2openapi from 'swagger2openapi';
|
|
8
|
+
const yaml = require('js-yaml');
|
|
9
|
+
const IdentifierRegexp = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
|
|
10
|
+
/**
|
|
11
|
+
* Import and parse the openapi spec from a yaml/json
|
|
12
|
+
*/
|
|
13
|
+
const importSpecs = (data, extension) => {
|
|
14
|
+
const schema = extension === 'yaml' ? yaml.load(data) : JSON.parse(data);
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
if (!schema.openapi || !schema.openapi.startsWith('3.')) {
|
|
17
|
+
swagger2openapi.convertObj(schema, {}, (err, convertedObj) => {
|
|
18
|
+
if (err) {
|
|
19
|
+
reject(err);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
resolve(convertedObj.openapi);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
resolve(schema);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Discriminator helper for `ReferenceObject`
|
|
33
|
+
*/
|
|
34
|
+
export const isReference = (property) => {
|
|
35
|
+
return Boolean(property.$ref);
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Return the typescript equivalent of open-api data type
|
|
39
|
+
*/
|
|
40
|
+
export const getScalar = (item) => {
|
|
41
|
+
const nullable = item.nullable ? ' | null' : '';
|
|
42
|
+
switch (item.type) {
|
|
43
|
+
case 'number':
|
|
44
|
+
case 'integer':
|
|
45
|
+
return 'number' + nullable;
|
|
46
|
+
case 'boolean':
|
|
47
|
+
return 'boolean' + nullable;
|
|
48
|
+
case 'array':
|
|
49
|
+
return getArray(item) + nullable;
|
|
50
|
+
case 'string':
|
|
51
|
+
return (item.enum ? `"${item.enum.join(`" | "`)}"` : 'string') + nullable;
|
|
52
|
+
case 'object':
|
|
53
|
+
default:
|
|
54
|
+
return getObject(item) + nullable;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Return the output type from the $ref
|
|
59
|
+
*/
|
|
60
|
+
export const getRef = ($ref) => {
|
|
61
|
+
if ($ref.startsWith('#/components/schemas')) {
|
|
62
|
+
return pascal($ref.replace('#/components/schemas/', ''));
|
|
63
|
+
}
|
|
64
|
+
else if ($ref.startsWith('#/components/responses')) {
|
|
65
|
+
return pascal($ref.replace('#/components/responses/', '')) + 'Response';
|
|
66
|
+
}
|
|
67
|
+
else if ($ref.startsWith('#/components/parameters')) {
|
|
68
|
+
return pascal($ref.replace('#/components/parameters/', '')) + 'Parameter';
|
|
69
|
+
}
|
|
70
|
+
else if ($ref.startsWith('#/components/requestBodies')) {
|
|
71
|
+
return pascal($ref.replace('#/components/requestBodies/', '')) + 'RequestBody';
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
throw new Error('This library only resolve $ref that are include into `#/components/*` for now');
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Return the output type from an array
|
|
79
|
+
*/
|
|
80
|
+
export const getArray = (item) => {
|
|
81
|
+
if (item.items) {
|
|
82
|
+
if (!isReference(item.items) && (item.items.oneOf || item.items.allOf || item.items.enum)) {
|
|
83
|
+
return `(${resolveValue(item.items)})[]`;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
return `${resolveValue(item.items)}[]`;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
throw new Error('All arrays must have an `items` key define');
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Return the output type from an object
|
|
95
|
+
*/
|
|
96
|
+
export const getObject = (item) => {
|
|
97
|
+
if (isReference(item)) {
|
|
98
|
+
return getRef(item.$ref);
|
|
99
|
+
}
|
|
100
|
+
if (item.allOf) {
|
|
101
|
+
return item.allOf.map(resolveValue).join(' & ');
|
|
102
|
+
}
|
|
103
|
+
if (item.oneOf) {
|
|
104
|
+
return item.oneOf.map(resolveValue).join(' | ');
|
|
105
|
+
}
|
|
106
|
+
if (!item.type && !item.properties && !item.additionalProperties) {
|
|
107
|
+
return '{}';
|
|
108
|
+
}
|
|
109
|
+
// Free form object (https://swagger.io/docs/specification/data-models/data-types/#free-form)
|
|
110
|
+
if (item.type === 'object' &&
|
|
111
|
+
!item.properties &&
|
|
112
|
+
(!item.additionalProperties || item.additionalProperties === true || isEmpty(item.additionalProperties))) {
|
|
113
|
+
return '{[key: string]: any}';
|
|
114
|
+
}
|
|
115
|
+
// Consolidation of item.properties & item.additionalProperties
|
|
116
|
+
let output = '{\n';
|
|
117
|
+
if (item.properties) {
|
|
118
|
+
output += Object.entries(item.properties)
|
|
119
|
+
.map(([key, prop]) => {
|
|
120
|
+
const doc = isReference(prop) ? '' : formatDescription(prop.description, 2);
|
|
121
|
+
const isRequired = (item.required || []).includes(key);
|
|
122
|
+
const processedKey = IdentifierRegexp.test(key) ? key : `"${key}"`;
|
|
123
|
+
return ` ${doc}${processedKey}${isRequired ? '' : '?'}: ${resolveValue(prop)};`;
|
|
124
|
+
})
|
|
125
|
+
.join('\n');
|
|
126
|
+
}
|
|
127
|
+
if (item.additionalProperties) {
|
|
128
|
+
if (item.properties) {
|
|
129
|
+
output += '\n';
|
|
130
|
+
}
|
|
131
|
+
output += ` [key: string]: ${item.additionalProperties === true ? 'any' : resolveValue(item.additionalProperties)};`;
|
|
132
|
+
}
|
|
133
|
+
if (item.properties || item.additionalProperties) {
|
|
134
|
+
if (output === '{\n') {
|
|
135
|
+
return '{}';
|
|
136
|
+
}
|
|
137
|
+
return output + '\n}';
|
|
138
|
+
}
|
|
139
|
+
return item.type === 'object' ? '{[key: string]: any}' : 'any';
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* Resolve the value of a schema object to a proper type definition.
|
|
143
|
+
*/
|
|
144
|
+
export const resolveValue = (schema) => isReference(schema) ? getRef(schema.$ref) : getScalar(schema);
|
|
145
|
+
/**
|
|
146
|
+
* Extract responses / request types from open-api specs
|
|
147
|
+
*/
|
|
148
|
+
export const getResReqTypes = (responsesOrRequests) => uniq(responsesOrRequests.map(([_, res]) => {
|
|
149
|
+
if (!res) {
|
|
150
|
+
return 'void';
|
|
151
|
+
}
|
|
152
|
+
if (isReference(res)) {
|
|
153
|
+
return getRef(res.$ref);
|
|
154
|
+
}
|
|
155
|
+
if (res.content) {
|
|
156
|
+
for (let contentType of Object.keys(res.content)) {
|
|
157
|
+
if (contentType.startsWith('application/json') ||
|
|
158
|
+
contentType.startsWith('application/octet-stream')) {
|
|
159
|
+
const schema = res.content[contentType].schema;
|
|
160
|
+
return resolveValue(schema);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return 'void';
|
|
164
|
+
}
|
|
165
|
+
return 'void';
|
|
166
|
+
})).join(' | ');
|
|
167
|
+
/**
|
|
168
|
+
* Return every params in a path
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```
|
|
172
|
+
* getParamsInPath("/pet/{category}/{name}/");
|
|
173
|
+
* // => ["category", "name"]
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
export const getParamsInPath = (path) => {
|
|
177
|
+
let n;
|
|
178
|
+
const output = [];
|
|
179
|
+
const templatePathRegex = /\{(\w+)}/g;
|
|
180
|
+
while ((n = templatePathRegex.exec(path)) !== null) {
|
|
181
|
+
output.push(n[1]);
|
|
182
|
+
}
|
|
183
|
+
return output;
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* Generate the interface string
|
|
187
|
+
*/
|
|
188
|
+
export const generateInterface = (name, schema) => {
|
|
189
|
+
const scalar = getScalar(schema);
|
|
190
|
+
return `${formatDescription(schema.description)}export interface ${pascal(name)} ${scalar}`;
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* Propagate every `discriminator.propertyName` mapping to the original ref
|
|
194
|
+
*
|
|
195
|
+
* Note: This method directly mutate the `specs` object.
|
|
196
|
+
*/
|
|
197
|
+
export const resolveDiscriminator = (specs) => {
|
|
198
|
+
if (specs.components && specs.components.schemas) {
|
|
199
|
+
Object.values(specs.components.schemas).forEach((schema) => {
|
|
200
|
+
if (isReference(schema) || !schema.discriminator || !schema.discriminator.mapping) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
const { mapping, propertyName } = schema.discriminator;
|
|
204
|
+
Object.entries(mapping).forEach(([name, ref]) => {
|
|
205
|
+
if (!ref.startsWith('#/components/schemas/')) {
|
|
206
|
+
throw new Error('Discriminator mapping outside of `#/components/schemas` is not supported');
|
|
207
|
+
}
|
|
208
|
+
set(specs, `components.schemas.${ref.slice('#/components/schemas/'.length)}.properties.${propertyName}.enum`, [name]);
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
/**
|
|
214
|
+
* Extract all types from #/components/schemas
|
|
215
|
+
*/
|
|
216
|
+
export const generateSchemasDefinition = (schemas = {}) => {
|
|
217
|
+
if (isEmpty(schemas)) {
|
|
218
|
+
return '';
|
|
219
|
+
}
|
|
220
|
+
return (Object.entries(schemas)
|
|
221
|
+
.map(([name, schema]) => !isReference(schema) &&
|
|
222
|
+
(!schema.type || schema.type === 'object') &&
|
|
223
|
+
!schema.allOf &&
|
|
224
|
+
!schema.oneOf &&
|
|
225
|
+
!isReference(schema) &&
|
|
226
|
+
!schema.nullable
|
|
227
|
+
? generateInterface(name, schema)
|
|
228
|
+
: `${formatDescription(isReference(schema) ? undefined : schema.description)}export type ${pascal(name)} = ${resolveValue(schema)};`)
|
|
229
|
+
.join('\n\n') + '\n');
|
|
230
|
+
};
|
|
231
|
+
/**
|
|
232
|
+
* Extract all types from #/components/requestBodies
|
|
233
|
+
*/
|
|
234
|
+
export const generateRequestBodiesDefinition = (requestBodies = {}) => {
|
|
235
|
+
if (isEmpty(requestBodies)) {
|
|
236
|
+
return '';
|
|
237
|
+
}
|
|
238
|
+
return ('\n' +
|
|
239
|
+
Object.entries(requestBodies)
|
|
240
|
+
.map(([name, requestBody]) => {
|
|
241
|
+
const doc = isReference(requestBody) ? '' : formatDescription(requestBody.description);
|
|
242
|
+
const type = getResReqTypes([['', requestBody]]);
|
|
243
|
+
const isEmptyInterface = type === '{}';
|
|
244
|
+
if (isEmptyInterface) {
|
|
245
|
+
return `export interface ${pascal(name)}RequestBody ${type}`;
|
|
246
|
+
}
|
|
247
|
+
else if (type.includes('{') && !type.includes('|') && !type.includes('&')) {
|
|
248
|
+
return `${doc}export interface ${pascal(name)}RequestBody ${type}`;
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
return `${doc}export type ${pascal(name)}RequestBody = ${type};`;
|
|
252
|
+
}
|
|
253
|
+
})
|
|
254
|
+
.join('\n\n') +
|
|
255
|
+
'\n');
|
|
256
|
+
};
|
|
257
|
+
/**
|
|
258
|
+
* Extract all types from #/components/responses
|
|
259
|
+
*/
|
|
260
|
+
export const generateResponsesDefinition = (responses = {}) => {
|
|
261
|
+
if (isEmpty(responses)) {
|
|
262
|
+
return '';
|
|
263
|
+
}
|
|
264
|
+
return ('\n' +
|
|
265
|
+
Object.entries(responses)
|
|
266
|
+
.map(([name, response]) => {
|
|
267
|
+
const doc = isReference(response) ? '' : formatDescription(response.description);
|
|
268
|
+
const type = getResReqTypes([['', response]]);
|
|
269
|
+
const isEmptyInterface = type === '{}';
|
|
270
|
+
if (isEmptyInterface) {
|
|
271
|
+
return `export interface RQ${pascal(name)}Response ${type}`;
|
|
272
|
+
}
|
|
273
|
+
else if (type.includes('{') && !type.includes('|') && !type.includes('&')) {
|
|
274
|
+
return `${doc}export interface RQ${pascal(name)}Response ${type}`;
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
return `${doc}export type RQ${pascal(name)}Response = ${type};`;
|
|
278
|
+
}
|
|
279
|
+
})
|
|
280
|
+
.join('\n\n') +
|
|
281
|
+
'\n');
|
|
282
|
+
};
|
|
283
|
+
/**
|
|
284
|
+
* Format a description to code documentation.
|
|
285
|
+
*/
|
|
286
|
+
export const formatDescription = (description, tabSize = 0) => description
|
|
287
|
+
? `/**\n${description
|
|
288
|
+
.split('\n')
|
|
289
|
+
.map((i) => `${' '.repeat(tabSize)} * ${i}`)
|
|
290
|
+
.join('\n')}\n${' '.repeat(tabSize)} */\n${' '.repeat(tabSize)}`
|
|
291
|
+
: '';
|
|
292
|
+
/**
|
|
293
|
+
* Generate a react-query component from openapi operation specs
|
|
294
|
+
*/
|
|
295
|
+
export const generateRestfulComponent = (operation, verb, route, operationIds, parameters = [], schemasComponents) => {
|
|
296
|
+
if (!operation.operationId) {
|
|
297
|
+
throw new Error(`Every path must have a operationId - No operationId set for ${verb} ${route}`);
|
|
298
|
+
}
|
|
299
|
+
if (operationIds.includes(operation.operationId)) {
|
|
300
|
+
throw new Error(`"${operation.operationId}" is duplicated in your schema definition!`);
|
|
301
|
+
}
|
|
302
|
+
operationIds.push(operation.operationId);
|
|
303
|
+
route = route.replace(/\{/g, '${'); // `/pet/{id}` => `/pet/${id}`
|
|
304
|
+
// Remove the last param of the route if we are in the DELETE case
|
|
305
|
+
let lastParamInTheRoute = null;
|
|
306
|
+
const componentName = pascal(operation.operationId);
|
|
307
|
+
const isOk = ([statusCode]) => statusCode.toString().startsWith('2');
|
|
308
|
+
const responseTypes = getResReqTypes(Object.entries(operation.responses).filter(isOk)) || 'void';
|
|
309
|
+
const requestBodyTypes = getResReqTypes([['body', operation.requestBody]]);
|
|
310
|
+
const needAResponseComponent = true;
|
|
311
|
+
const paramsInPath = getParamsInPath(route).filter((param) => !(verb === 'delete' && param === lastParamInTheRoute));
|
|
312
|
+
const { query: queryParams = [], path: pathParams = [] } = groupBy([...parameters, ...(operation.parameters || [])].map((p) => {
|
|
313
|
+
if (isReference(p)) {
|
|
314
|
+
return get(schemasComponents, p.$ref.replace('#/components/', '').replace('/', '.'));
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
return p;
|
|
318
|
+
}
|
|
319
|
+
}), 'in');
|
|
320
|
+
const paramsTypes = paramsInPath
|
|
321
|
+
.map((p) => {
|
|
322
|
+
try {
|
|
323
|
+
const { name, required, schema } = pathParams.find((i) => i.name === p);
|
|
324
|
+
return `${name}${required ? '' : '?'}: ${resolveValue(schema)}`;
|
|
325
|
+
}
|
|
326
|
+
catch (err) {
|
|
327
|
+
throw new Error(`The path params ${p} can't be found in parameters (${operation.operationId})`);
|
|
328
|
+
}
|
|
329
|
+
})
|
|
330
|
+
.join('; ');
|
|
331
|
+
const queryParamsType = queryParams
|
|
332
|
+
.map((p) => {
|
|
333
|
+
const processedName = IdentifierRegexp.test(p.name) ? p.name : `"${p.name}"`;
|
|
334
|
+
return `${formatDescription(p.description, 2)}${processedName}${p.required ? '' : '?'}: ${resolveValue(p.schema)}`;
|
|
335
|
+
})
|
|
336
|
+
.join(';\n ');
|
|
337
|
+
// Retrieve the type of the param for delete verb
|
|
338
|
+
const lastParamInTheRouteDefinition = operation.parameters && lastParamInTheRoute
|
|
339
|
+
? operation.parameters.find((p) => {
|
|
340
|
+
if (isReference(p)) {
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
return p.name === lastParamInTheRoute;
|
|
344
|
+
}) // Reference is not possible
|
|
345
|
+
: { schema: { type: 'string' } };
|
|
346
|
+
if (!lastParamInTheRouteDefinition) {
|
|
347
|
+
throw new Error(`The path params ${lastParamInTheRoute} can't be found in parameters (${operation.operationId})`);
|
|
348
|
+
}
|
|
349
|
+
let genericsTypes = `${needAResponseComponent ? componentName + 'Res' : responseTypes}`;
|
|
350
|
+
if (verb !== 'get') {
|
|
351
|
+
genericsTypes = `${needAResponseComponent ? componentName + 'Res' : responseTypes}`;
|
|
352
|
+
}
|
|
353
|
+
const description = formatDescription(operation.summary && operation.description
|
|
354
|
+
? `${operation.summary}\n\n${operation.description}`
|
|
355
|
+
: `${operation.summary || ''}${operation.description || ''}`);
|
|
356
|
+
let output = `\n\n${description}`;
|
|
357
|
+
const typeOrInterface = `type ${componentName}Res =`;
|
|
358
|
+
output += `
|
|
359
|
+
${needAResponseComponent ? `export ${typeOrInterface} ${responseTypes}` : ''}
|
|
360
|
+
`;
|
|
361
|
+
const queryParam = queryParamsType && queryParamsType !== 'void' ? `${queryParamsType}` : '';
|
|
362
|
+
const requestBodyComponent = requestBodyTypes && requestBodyTypes !== 'void' ? `${requestBodyTypes}` : '';
|
|
363
|
+
// QUERIES
|
|
364
|
+
if (!requestBodyComponent && paramsInPath.length && !queryParam) {
|
|
365
|
+
output += `
|
|
366
|
+
type ${componentName}Params = {${paramsTypes}};
|
|
367
|
+
use${componentName}Query.fetch = async (props: ${componentName}Params ) => {
|
|
368
|
+
const result = await api.${verb}<${genericsTypes}>(\`${route.replace(/\{/g, '{props.')}\`);
|
|
369
|
+
return result.data;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
use${componentName}Query.baseKey = (): QueryKey => ["${componentName.toLowerCase()}"];
|
|
373
|
+
use${componentName}Query.queryKey = (params: ${componentName}Params ): QueryKey => [...use${componentName}Query.baseKey(), params];
|
|
374
|
+
|
|
375
|
+
type ${componentName}QueryProps<T = ${genericsTypes}> = {
|
|
376
|
+
options?: UseQueryOptions<${genericsTypes}, AxiosError, T, any>
|
|
377
|
+
} & ${componentName}Params
|
|
378
|
+
|
|
379
|
+
export function use${componentName}Query<T = ${genericsTypes}>({ options = {}, ...props }: ${componentName}QueryProps<T>) {
|
|
380
|
+
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props),
|
|
381
|
+
{ enabled: !!props.${paramsInPath.join(' && !!props.')}, ...options }
|
|
382
|
+
);}
|
|
383
|
+
|
|
384
|
+
type ${componentName}MutationProps<T> = {
|
|
385
|
+
options?: UseMutationOptions<${genericsTypes}, AxiosError, ${componentName}Params, T>
|
|
386
|
+
}
|
|
387
|
+
export function use${componentName}Mutation<T = ${genericsTypes}>(props?: ${componentName}MutationProps<T>) {
|
|
388
|
+
return useMutation(async ({${paramsInPath.join(', ')}}) => {
|
|
389
|
+
const result = await api.${verb}<${genericsTypes}>(\`${route}\`)
|
|
390
|
+
return result.data
|
|
391
|
+
},
|
|
392
|
+
props?.options
|
|
393
|
+
)};`;
|
|
394
|
+
}
|
|
395
|
+
if (!requestBodyComponent && paramsInPath.length && queryParam) {
|
|
396
|
+
output += `
|
|
397
|
+
type ${componentName}Params = {
|
|
398
|
+
${paramsTypes}
|
|
399
|
+
${queryParamsType}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
use${componentName}Query.fetch = async (props: ${componentName}Params) => {
|
|
403
|
+
const {${paramsInPath.join(', ')}, ...queryParams} = props
|
|
404
|
+
const params = queryString.stringify(queryParams);
|
|
405
|
+
const result = await api.${verb}<${genericsTypes}>(\`${route}?\${params}\`)
|
|
406
|
+
return result.data;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
use${componentName}Query.baseKey = (): QueryKey => ["${componentName.toLowerCase()}"];
|
|
410
|
+
|
|
411
|
+
use${componentName}Query.queryKey = (params: ${componentName}Params): QueryKey => [...use${componentName}Query.baseKey(), params];
|
|
412
|
+
|
|
413
|
+
type ${componentName}QueryProps<T = ${genericsTypes}> = {
|
|
414
|
+
options?: UseQueryOptions<${genericsTypes}, AxiosError, T, any>
|
|
415
|
+
} & ${componentName}Params
|
|
416
|
+
|
|
417
|
+
export function use${componentName}Query<T = ${genericsTypes}>({ options = {}, ...props }: ${componentName}QueryProps<T>) {
|
|
418
|
+
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props), { enabled: !!props.${paramsInPath.join(' && !!props.')}, ...options }
|
|
419
|
+
);}
|
|
420
|
+
|
|
421
|
+
type ${componentName}MutationProps<T> = {
|
|
422
|
+
options?: UseMutationOptions<${genericsTypes}, AxiosError, ${componentName}Params, T>
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
export function use${componentName}Mutation<T = ${genericsTypes}>(props?: ${componentName}MutationProps<T>) {
|
|
426
|
+
return useMutation(async (data) => {
|
|
427
|
+
const {${paramsInPath.join(', ')}, ...queryParams} = data
|
|
428
|
+
const params = queryString.stringify(queryParams);
|
|
429
|
+
const result = await api.${verb}<${genericsTypes}>(\`${route}?\${params}\`)
|
|
430
|
+
return result.data
|
|
431
|
+
},
|
|
432
|
+
props?.options
|
|
433
|
+
)};`;
|
|
434
|
+
}
|
|
435
|
+
if (!requestBodyComponent && !paramsInPath.length && !queryParam) {
|
|
436
|
+
output += `
|
|
437
|
+
use${componentName}Query.baseKey = (): QueryKey => ["${componentName.toLowerCase()}"];
|
|
438
|
+
use${componentName}Query.queryKey = (): QueryKey => use${componentName}Query.baseKey()
|
|
439
|
+
|
|
440
|
+
use${componentName}Query.fetch = async () => {
|
|
441
|
+
const result = await api.${verb}<${genericsTypes}>(\`${route}\`);
|
|
442
|
+
return result.data;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
type ${componentName}QueryProps<T = ${genericsTypes}> = {
|
|
446
|
+
options?: UseQueryOptions<${genericsTypes}, AxiosError, T, any>
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
export function use${componentName}Query<T = ${genericsTypes}>(props?: ${componentName}QueryProps<T>) {
|
|
450
|
+
return useQuery(use${componentName}Query.queryKey(), use${componentName}Query.fetch, props?.options
|
|
451
|
+
);}
|
|
452
|
+
|
|
453
|
+
type ${componentName}MutationProps<T> = {
|
|
454
|
+
options?: UseMutationOptions<${genericsTypes}, AxiosError, void, T>
|
|
455
|
+
}
|
|
456
|
+
export function use${componentName}Mutation<T = ${genericsTypes}>(props?: ${componentName}MutationProps<T>) {
|
|
457
|
+
return useMutation(async () => {
|
|
458
|
+
const result = await api.${verb}<${genericsTypes}>(\`${route}\`);
|
|
459
|
+
return result.data;
|
|
460
|
+
},
|
|
461
|
+
props?.options
|
|
462
|
+
)};
|
|
463
|
+
`;
|
|
464
|
+
}
|
|
465
|
+
if (!requestBodyComponent && !paramsInPath.length && queryParam) {
|
|
466
|
+
output += `
|
|
467
|
+
type ${componentName}Params = {
|
|
468
|
+
${queryParamsType}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
use${componentName}Query.fetch = async (props: ${componentName}Params) => {
|
|
472
|
+
const params = queryString.stringify({${queryParams
|
|
473
|
+
.map((param) => `${param.name}: props.${param.name}`)
|
|
474
|
+
.join(',')}});
|
|
475
|
+
const result = await api.${verb}<${genericsTypes}>(\`${route}?\${params}\`)
|
|
476
|
+
return result.data;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
use${componentName}Query.baseKey = (): QueryKey => ["${componentName.toLowerCase()}"];
|
|
480
|
+
use${componentName}Query.queryKey = (params: ${componentName}Params ): QueryKey => [...use${componentName}Query.baseKey(), params];
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
type ${componentName}QueryProps<T = ${genericsTypes}> = {
|
|
484
|
+
options?: UseQueryOptions<${genericsTypes}, AxiosError, T, any>
|
|
485
|
+
} & ${componentName}Params
|
|
486
|
+
|
|
487
|
+
export function use${componentName}Query<T = ${genericsTypes}>({ options = {}, ...props }: ${componentName}QueryProps<T>) {
|
|
488
|
+
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props),
|
|
489
|
+
{
|
|
490
|
+
enabled: !!props.${queryParams.map((param) => param.name).join(' && !!props.')},
|
|
491
|
+
...options
|
|
492
|
+
}
|
|
493
|
+
);}
|
|
494
|
+
|
|
495
|
+
type ${componentName}MutationProps<T> = {
|
|
496
|
+
options?: UseMutationOptions<${genericsTypes}, AxiosError, ${componentName}Params, T>
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
export function use${componentName}Mutation<T = ${genericsTypes}>(props?: ${componentName}MutationProps<T>) {
|
|
500
|
+
return useMutation(async (data) => {
|
|
501
|
+
const params = queryString.stringify({${queryParams
|
|
502
|
+
.map((param) => `${param.name}: data.${param.name}`)
|
|
503
|
+
.join(',')}});
|
|
504
|
+
const result = await api.${verb}<${genericsTypes}>(\`${route}?\${params}\`)
|
|
505
|
+
return result.data;
|
|
506
|
+
},
|
|
507
|
+
props?.options
|
|
508
|
+
)};`;
|
|
509
|
+
}
|
|
510
|
+
if (requestBodyComponent && !paramsInPath.length && !queryParam) {
|
|
511
|
+
output += `
|
|
512
|
+
use${componentName}Query.fetch = async (body:${requestBodyComponent}) => {
|
|
513
|
+
const result = await api.${verb}<${genericsTypes}>(\`${route}\`, body)
|
|
514
|
+
return result.data
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
use${componentName}Query.baseKey = (): QueryKey => ["${componentName.toLowerCase()}"];
|
|
518
|
+
use${componentName}Query.queryKey = (params:${requestBodyComponent}): QueryKey => [...use${componentName}Query.baseKey(), params];
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
type ${componentName}QueryProps<T = ${genericsTypes}> = {
|
|
522
|
+
options?: UseQueryOptions<${genericsTypes}, AxiosError, T, any>
|
|
523
|
+
} & ${requestBodyComponent}
|
|
524
|
+
|
|
525
|
+
export function use${componentName}Query<T = ${genericsTypes}>({ options = {}, ...body }: ${componentName}QueryProps<T>) {
|
|
526
|
+
return useQuery(use${componentName}Query.queryKey(body), async () => use${componentName}Query.fetch(body), options
|
|
527
|
+
);}
|
|
528
|
+
|
|
529
|
+
type ${componentName}MutationProps<T> = {
|
|
530
|
+
options?: UseMutationOptions<${genericsTypes}, AxiosError, ${requestBodyComponent}, T>
|
|
531
|
+
}
|
|
532
|
+
export function use${componentName}Mutation<T = ${genericsTypes}>(props?: ${componentName}MutationProps<T>) {
|
|
533
|
+
return useMutation(async (body) => {
|
|
534
|
+
const result = await api.${verb}<${genericsTypes}>(\`${route}\`, body)
|
|
535
|
+
return result.data
|
|
536
|
+
},
|
|
537
|
+
props?.options
|
|
538
|
+
)};`;
|
|
539
|
+
}
|
|
540
|
+
if (requestBodyComponent && paramsInPath.length && !queryParam) {
|
|
541
|
+
output += `
|
|
542
|
+
// HDHD
|
|
543
|
+
type ${componentName}Params = {${paramsTypes}} & ${requestBodyComponent}
|
|
544
|
+
|
|
545
|
+
use${componentName}Query.fetch = async (props: ${componentName}Params) => {
|
|
546
|
+
const {${paramsInPath.join(', ')}, ...body} = props
|
|
547
|
+
const result = await api.${verb}<${genericsTypes}>(\`${route}\`, body)
|
|
548
|
+
return result.data
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
use${componentName}Query.baseKey = (): QueryKey => ["${componentName.toLowerCase()}"];
|
|
552
|
+
use${componentName}Query.queryKey = (params: ${componentName}Params ): QueryKey => [...use${componentName}Query.baseKey(), params];
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
type ${componentName}QueryProps<T = ${genericsTypes}> = {
|
|
556
|
+
options?: UseQueryOptions<${genericsTypes}, AxiosError, T, any>
|
|
557
|
+
} & ${componentName}Params
|
|
558
|
+
|
|
559
|
+
export function use${componentName}Query<T = ${genericsTypes}>({ options = {}, ...props }: ${componentName}QueryProps<T>) {
|
|
560
|
+
return useQuery(use${componentName}Query.queryKey(props), async () => use${componentName}Query.fetch(props), { enabled: !!props.${paramsInPath.join(' && !!props.')}, ...options }
|
|
561
|
+
);}
|
|
562
|
+
|
|
563
|
+
type ${componentName}MutationProps<T> = {
|
|
564
|
+
options?: UseMutationOptions<${genericsTypes}, AxiosError,${componentName}Params, T>
|
|
565
|
+
}
|
|
566
|
+
export function use${componentName}Mutation<T = ${genericsTypes}>(props?: ${componentName}MutationProps<T>) {
|
|
567
|
+
return useMutation(async (body) => use${componentName}Query.fetch(body),
|
|
568
|
+
props?.options
|
|
569
|
+
)};`;
|
|
570
|
+
}
|
|
571
|
+
if (requestBodyComponent && queryParam) {
|
|
572
|
+
output += `// TODO: CODEGEN DOES NOT SUPPORT QUERYPARAM AND REQUESTBODY`;
|
|
573
|
+
}
|
|
574
|
+
return output;
|
|
575
|
+
};
|
|
576
|
+
/**
|
|
577
|
+
* Main entry of the generator. Generate react-query component from openAPI.
|
|
578
|
+
*/
|
|
579
|
+
const importOpenApi = async ({ data, format }) => {
|
|
580
|
+
const operationIds = [];
|
|
581
|
+
let specs = await importSpecs(data, format);
|
|
582
|
+
resolveDiscriminator(specs);
|
|
583
|
+
let output = `
|
|
584
|
+
import { useQuery, useMutation, UseQueryOptions, UseMutationOptions, QueryKey } from 'react-query';
|
|
585
|
+
import queryString from 'query-string';
|
|
586
|
+
import {AxiosError} from 'axios';
|
|
587
|
+
import { api } from 'api';
|
|
588
|
+
`;
|
|
589
|
+
output += '\n\n// SCEHMAS\n';
|
|
590
|
+
output += generateSchemasDefinition(specs.components && specs.components.schemas);
|
|
591
|
+
output += '\n\n// RESPONSES\n';
|
|
592
|
+
output += generateResponsesDefinition(specs.components && specs.components.responses);
|
|
593
|
+
output += '\n\n// REQUEST BODIES\n';
|
|
594
|
+
output += generateRequestBodiesDefinition(specs.components && specs.components.requestBodies);
|
|
595
|
+
output += '\n\n// HOOKS\n';
|
|
596
|
+
Object.entries(specs.paths).forEach(([route, verbs]) => {
|
|
597
|
+
Object.entries(verbs).forEach(([verb, operation]) => {
|
|
598
|
+
if (['get', 'post', 'patch', 'put', 'delete'].includes(verb) && !operation.deprecated) {
|
|
599
|
+
output += generateRestfulComponent(operation, verb, route, operationIds, verbs.parameters, specs.components);
|
|
600
|
+
}
|
|
601
|
+
});
|
|
602
|
+
});
|
|
603
|
+
return output;
|
|
604
|
+
};
|
|
605
|
+
export default importOpenApi;
|
package/lib/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|