Skip to content

Commit 022f600

Browse files
committed
refactor(codegen): require explicit selection in hooks
1 parent 97f9cf3 commit 022f600

8 files changed

Lines changed: 329 additions & 452 deletions

File tree

graphql/codegen/src/__tests__/codegen/__snapshots__/react-query-hooks.test.ts.snap

Lines changed: 96 additions & 194 deletions
Large diffs are not rendered by default.

graphql/codegen/src/core/codegen/barrel.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,12 @@ export function generateMainBarrel(
172172
"import { useCarsQuery, useCreateCarMutation } from './generated';",
173173
'',
174174
'function MyComponent() {',
175-
' const { data, isLoading } = useCarsQuery({ first: 10 });',
176-
' const { mutate } = useCreateCarMutation();',
175+
' const { data, isLoading } = useCarsQuery({',
176+
' selection: { fields: { id: true }, first: 10 },',
177+
' });',
178+
' const { mutate } = useCreateCarMutation({',
179+
' selection: { fields: { id: true } },',
180+
' });',
177181
' // ...',
178182
'}',
179183
'```',

graphql/codegen/src/core/codegen/custom-mutations.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ function generateCustomMutationHookInternal(
260260
)
261261
: undefined;
262262

263-
const selectObj = t.objectExpression([
263+
const selectArgExpr = t.objectExpression([
264264
objectProp(
265265
'select',
266266
t.memberExpression(t.identifier('args'), t.identifier('select')),
@@ -279,13 +279,18 @@ function generateCustomMutationHookInternal(
279279
'mutation',
280280
operation.name,
281281
[t.identifier('variables')],
282-
selectObj,
282+
selectArgExpr,
283283
),
284284
);
285285
} else {
286286
mutationFnExpr = t.arrowFunctionExpression(
287287
[],
288-
getClientCustomCallUnwrap('mutation', operation.name, [], selectObj),
288+
getClientCustomCallUnwrap(
289+
'mutation',
290+
operation.name,
291+
[],
292+
selectArgExpr,
293+
),
289294
);
290295
}
291296

@@ -301,7 +306,7 @@ function generateCustomMutationHookInternal(
301306
exportFunction(
302307
hookName,
303308
null,
304-
[createFunctionParam('params', implParamType, true)],
309+
[createFunctionParam('params', implParamType)],
305310
body,
306311
),
307312
);

graphql/codegen/src/core/codegen/custom-queries.ts

Lines changed: 121 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,12 @@ export function generateCustomQueryHook(
268268
operation.description || `Query hook for ${operation.name}`;
269269
const argNames = operation.args.map((a) => a.name).join(', ');
270270
const exampleCall = hasArgs
271-
? `${hookName}({ ${argNames} })`
272-
: `${hookName}()`;
271+
? hasSelect
272+
? `${hookName}({ variables: { ${argNames} }, selection: { fields: { id: true } } })`
273+
: `${hookName}({ variables: { ${argNames} } })`
274+
: hasSelect
275+
? `${hookName}({ selection: { fields: { id: true } } })`
276+
: `${hookName}()`;
273277

274278
if (hasSelect) {
275279
// Overload 1: with selection.fields
@@ -344,20 +348,24 @@ export function generateCustomQueryHook(
344348
const implParam = createFunctionParam(
345349
'params',
346350
implParamType,
347-
!hasRequiredArgs,
351+
false,
348352
);
349353

350354
const body: t.Statement[] = [];
351355
if (hasArgs) {
352356
body.push(
353357
constDecl(
354358
'variables',
355-
t.optionalMemberExpression(
356-
t.identifier('params'),
357-
t.identifier('variables'),
358-
false,
359-
true,
360-
),
359+
hasRequiredArgs
360+
? t.memberExpression(
361+
t.identifier('params'),
362+
t.identifier('variables'),
363+
)
364+
: t.logicalExpression(
365+
'??',
366+
t.memberExpression(t.identifier('params'), t.identifier('variables')),
367+
t.objectExpression([]),
368+
),
361369
),
362370
);
363371
}
@@ -398,7 +406,7 @@ export function generateCustomQueryHook(
398406
body.push(voidStatement('_selection'));
399407
}
400408

401-
const selectObj = t.objectExpression([
409+
const selectArgExpr = t.objectExpression([
402410
objectProp(
403411
'select',
404412
t.memberExpression(t.identifier('args'), t.identifier('select')),
@@ -409,9 +417,9 @@ export function generateCustomQueryHook(
409417
hasRequiredArgs
410418
? t.tsNonNullExpression(t.identifier('variables'))
411419
: t.identifier('variables'),
412-
selectObj,
420+
selectArgExpr,
413421
]
414-
: [selectObj];
422+
: [selectArgExpr];
415423
const queryFnExpr = t.arrowFunctionExpression(
416424
[],
417425
getClientCustomCallUnwrap(
@@ -511,12 +519,23 @@ export function generateCustomQueryHook(
511519
body.push(
512520
constDecl(
513521
'variables',
514-
t.optionalMemberExpression(
515-
t.identifier('params'),
516-
t.identifier('variables'),
517-
false,
518-
true,
519-
),
522+
hasRequiredArgs
523+
? t.optionalMemberExpression(
524+
t.identifier('params'),
525+
t.identifier('variables'),
526+
false,
527+
true,
528+
)
529+
: t.logicalExpression(
530+
'??',
531+
t.optionalMemberExpression(
532+
t.identifier('params'),
533+
t.identifier('variables'),
534+
false,
535+
true,
536+
),
537+
t.objectExpression([]),
538+
),
520539
),
521540
);
522541
const destructPattern = t.objectPattern([
@@ -604,7 +623,7 @@ export function generateCustomQueryHook(
604623
statements.push(
605624
exportFunction(
606625
hookName,
607-
null,
626+
createTDataTypeParam(resultTypeLiteral),
608627
[implParam],
609628
body,
610629
typeRef('UseQueryResult', [typeRef('TData')]),
@@ -617,8 +636,12 @@ export function generateCustomQueryHook(
617636
const fetchFnName = `fetch${ucFirst(operation.name)}Query`;
618637
const fetchArgNames = operation.args.map((a) => a.name).join(', ');
619638
const fetchExampleCall = hasArgs
620-
? `${fetchFnName}({ ${fetchArgNames} })`
621-
: `${fetchFnName}()`;
639+
? hasSelect
640+
? `${fetchFnName}({ variables: { ${fetchArgNames} }, selection: { fields: { id: true } } })`
641+
: `${fetchFnName}({ variables: { ${fetchArgNames} } })`
642+
: hasSelect
643+
? `${fetchFnName}({ selection: { fields: { id: true } } })`
644+
: `${fetchFnName}()`;
622645

623646
if (hasSelect) {
624647
// Overload 1: with fields
@@ -677,17 +700,18 @@ export function generateCustomQueryHook(
677700
fBody.push(
678701
constDecl(
679702
'variables',
680-
t.optionalMemberExpression(
681-
t.identifier('params'),
682-
t.identifier('variables'),
683-
false,
684-
true,
685-
),
703+
hasRequiredArgs
704+
? t.memberExpression(t.identifier('params'), t.identifier('variables'))
705+
: t.logicalExpression(
706+
'??',
707+
t.memberExpression(t.identifier('params'), t.identifier('variables')),
708+
t.objectExpression([]),
709+
),
686710
),
687711
);
688712
}
689713
fBody.push(buildSelectionArgsCall(selectTypeName!));
690-
const selectObj = t.objectExpression([
714+
const selectArgExpr = t.objectExpression([
691715
objectProp(
692716
'select',
693717
t.memberExpression(t.identifier('args'), t.identifier('select')),
@@ -698,9 +722,9 @@ export function generateCustomQueryHook(
698722
hasRequiredArgs
699723
? t.tsNonNullExpression(t.identifier('variables'))
700724
: t.identifier('variables'),
701-
selectObj,
725+
selectArgExpr,
702726
]
703-
: [selectObj];
727+
: [selectArgExpr];
704728
fBody.push(
705729
t.returnStatement(
706730
getClientCustomCallUnwrap(
@@ -714,7 +738,13 @@ export function generateCustomQueryHook(
714738
exportAsyncFunction(
715739
fetchFnName,
716740
null,
717-
[createFunctionParam('params', t.tsTypeLiteral(fImplProps))],
741+
[
742+
createFunctionParam(
743+
'params',
744+
t.tsTypeLiteral(fImplProps),
745+
false,
746+
),
747+
],
718748
fBody,
719749
),
720750
);
@@ -731,12 +761,23 @@ export function generateCustomQueryHook(
731761
fBody.push(
732762
constDecl(
733763
'variables',
734-
t.optionalMemberExpression(
735-
t.identifier('params'),
736-
t.identifier('variables'),
737-
false,
738-
true,
739-
),
764+
hasRequiredArgs
765+
? t.optionalMemberExpression(
766+
t.identifier('params'),
767+
t.identifier('variables'),
768+
false,
769+
true,
770+
)
771+
: t.logicalExpression(
772+
'??',
773+
t.optionalMemberExpression(
774+
t.identifier('params'),
775+
t.identifier('variables'),
776+
false,
777+
true,
778+
),
779+
t.objectExpression([]),
780+
),
740781
),
741782
);
742783
const fCallArgs = hasRequiredArgs
@@ -796,8 +837,12 @@ export function generateCustomQueryHook(
796837
const prefetchFnName = `prefetch${ucFirst(operation.name)}Query`;
797838
const prefetchArgNames = operation.args.map((a) => a.name).join(', ');
798839
const prefetchExampleCall = hasArgs
799-
? `${prefetchFnName}(queryClient, { ${prefetchArgNames} })`
800-
: `${prefetchFnName}(queryClient)`;
840+
? hasSelect
841+
? `${prefetchFnName}(queryClient, { variables: { ${prefetchArgNames} }, selection: { fields: { id: true } } })`
842+
: `${prefetchFnName}(queryClient, { variables: { ${prefetchArgNames} } })`
843+
: hasSelect
844+
? `${prefetchFnName}(queryClient, { selection: { fields: { id: true } } })`
845+
: `${prefetchFnName}(queryClient)`;
801846

802847
if (hasSelect) {
803848
// Overload 1: with fields
@@ -859,17 +904,21 @@ export function generateCustomQueryHook(
859904
pBody.push(
860905
constDecl(
861906
'variables',
862-
t.optionalMemberExpression(
863-
t.identifier('params'),
864-
t.identifier('variables'),
865-
false,
866-
true,
867-
),
907+
hasRequiredArgs
908+
? t.memberExpression(
909+
t.identifier('params'),
910+
t.identifier('variables'),
911+
)
912+
: t.logicalExpression(
913+
'??',
914+
t.memberExpression(t.identifier('params'), t.identifier('variables')),
915+
t.objectExpression([]),
916+
),
868917
),
869918
);
870919
}
871920
pBody.push(buildSelectionArgsCall(selectTypeName!));
872-
const selectObj = t.objectExpression([
921+
const selectArgExpr = t.objectExpression([
873922
objectProp(
874923
'select',
875924
t.memberExpression(t.identifier('args'), t.identifier('select')),
@@ -880,9 +929,9 @@ export function generateCustomQueryHook(
880929
hasRequiredArgs
881930
? t.tsNonNullExpression(t.identifier('variables'))
882931
: t.identifier('variables'),
883-
selectObj,
932+
selectArgExpr,
884933
]
885-
: [selectObj];
934+
: [selectArgExpr];
886935
const prefetchQueryCall = callExpr(
887936
t.memberExpression(
888937
t.identifier('queryClient'),
@@ -912,10 +961,14 @@ export function generateCustomQueryHook(
912961
null,
913962
[
914963
createFunctionParam('queryClient', typeRef('QueryClient')),
915-
createFunctionParam('params', t.tsTypeLiteral(pImplProps)),
964+
createFunctionParam(
965+
'params',
966+
t.tsTypeLiteral(pImplProps),
967+
false,
968+
),
916969
],
917970
pBody,
918-
t.tsVoidKeyword(),
971+
typeRef('Promise', [t.tsVoidKeyword()]),
919972
),
920973
);
921974
} else {
@@ -943,12 +996,23 @@ export function generateCustomQueryHook(
943996
pBody.push(
944997
constDecl(
945998
'variables',
946-
t.optionalMemberExpression(
947-
t.identifier('params'),
948-
t.identifier('variables'),
949-
false,
950-
true,
951-
),
999+
hasRequiredArgs
1000+
? t.optionalMemberExpression(
1001+
t.identifier('params'),
1002+
t.identifier('variables'),
1003+
false,
1004+
true,
1005+
)
1006+
: t.logicalExpression(
1007+
'??',
1008+
t.optionalMemberExpression(
1009+
t.identifier('params'),
1010+
t.identifier('variables'),
1011+
false,
1012+
true,
1013+
),
1014+
t.objectExpression([]),
1015+
),
9521016
),
9531017
);
9541018
const pCallArgs = hasRequiredArgs
@@ -1004,7 +1068,7 @@ export function generateCustomQueryHook(
10041068
null,
10051069
pParams,
10061070
pBody,
1007-
t.tsVoidKeyword(),
1071+
typeRef('Promise', [t.tsVoidKeyword()]),
10081072
);
10091073
addJSDocComment(pDecl, [
10101074
`Prefetch ${operation.name} for SSR or cache warming`,

0 commit comments

Comments
 (0)