@@ -12,6 +12,7 @@ import j, {
1212 FileInfo ,
1313 API ,
1414 Options ,
15+ TypeParameterInstantiation ,
1516} from 'jscodeshift'
1617import findImports from 'jscodeshift-find-imports'
1718import addImports from 'jscodeshift-add-imports'
@@ -40,6 +41,17 @@ function typeCast(
4041 return j . typeCastExpression ( node , typeAnnotation )
4142}
4243
44+ function makeFunctionTypeArguments (
45+ data : TypeAlias ,
46+ variables ?: TypeAlias | null | undefined
47+ ) : TypeParameterInstantiation {
48+ const params = [ j . genericTypeAnnotation ( j . identifier ( data . id . name ) , null ) ]
49+ if ( variables ) {
50+ params . push ( j . genericTypeAnnotation ( j . identifier ( variables . id . name ) , null ) )
51+ }
52+ return j . typeParameterInstantiation ( params )
53+ }
54+
4355export default function graphqlTypegenCore (
4456 { path : file , source : code } : FileInfo ,
4557 { j } : API ,
@@ -57,7 +69,7 @@ export default function graphqlTypegenCore(
5769 )
5870 }
5971 const config = applyConfigDefaults ( Object . assign ( packageConf , options ) )
60- const { tagName = 'gql' } = config
72+ const { tagName = 'gql' , useFunctionTypeArguments } = config
6173
6274 const root = j ( code )
6375 const { statement } = j . template
@@ -437,39 +449,48 @@ export default function graphqlTypegenCore(
437449 } )
438450 . forEach ( ( path : ASTPath < VariableDeclarator > ) : void => {
439451 const { data, variables } = onlyValue ( generatedTypes . query ) || { }
440- if ( ! data ) return
441- if (
442- path . node . id . type === 'Identifier' ||
443- path . node . id . type === 'ObjectPattern'
444- ) {
445- path . node . id . typeAnnotation = queryRenderPropsAnnotation (
452+ if ( ! data || path . node . init ?. type !== 'CallExpression' ) return
453+ if ( useFunctionTypeArguments ) {
454+ ; ( path . node . init as any ) . typeArguments = makeFunctionTypeArguments (
446455 data ,
447456 variables
448457 )
449- }
450- if ( path . node . init ?. type !== 'CallExpression' ) return
451- const options = path . node . init . arguments [ 1 ]
452- if ( variables && options && options . type === 'ObjectExpression' ) {
453- const variablesProp = options . properties . find (
454- p =>
455- p . type !== 'SpreadProperty' &&
456- p . type !== 'SpreadElement' &&
457- p . key . type === 'Identifier' &&
458- p . key . name === 'variables'
459- )
458+ } else {
460459 if (
461- variablesProp &&
462- variablesProp . type !== 'ObjectMethod' &&
463- variablesProp . type !== 'SpreadElement' &&
464- variablesProp . type !== 'SpreadProperty'
460+ path . node . id . type === 'Identifier' ||
461+ path . node . id . type === 'ObjectPattern'
465462 ) {
466- variablesProp . value = typeCast (
467- variablesProp . value as ExpressionKind ,
468- j . typeAnnotation (
469- j . genericTypeAnnotation ( j . identifier ( variables . id . name ) , null )
470- )
463+ path . node . id . typeAnnotation = queryRenderPropsAnnotation (
464+ data ,
465+ variables
471466 )
472467 }
468+ const options = path . node . init . arguments [ 1 ]
469+ if ( variables && options && options . type === 'ObjectExpression' ) {
470+ const variablesProp = options . properties . find (
471+ p =>
472+ p . type !== 'SpreadProperty' &&
473+ p . type !== 'SpreadElement' &&
474+ p . key . type === 'Identifier' &&
475+ p . key . name === 'variables'
476+ )
477+ if (
478+ variablesProp &&
479+ variablesProp . type !== 'ObjectMethod' &&
480+ variablesProp . type !== 'SpreadElement' &&
481+ variablesProp . type !== 'SpreadProperty'
482+ ) {
483+ variablesProp . value = typeCast (
484+ variablesProp . value as ExpressionKind ,
485+ j . typeAnnotation (
486+ j . genericTypeAnnotation (
487+ j . identifier ( variables . id . name ) ,
488+ null
489+ )
490+ )
491+ )
492+ }
493+ }
473494 }
474495 } )
475496 }
@@ -490,25 +511,32 @@ export default function graphqlTypegenCore(
490511 } ,
491512 } )
492513 . forEach ( ( path : ASTPath < VariableDeclarator > ) : void => {
493- const { data, mutationFunction } =
514+ const { data, variables , mutationFunction } =
494515 onlyValue ( generatedTypes . mutation ) || { }
495- if ( ! mutationFunction ) return
516+ if ( ! mutationFunction || ! data ) return
496517 const {
497518 node : { id } ,
498519 } = path
499- if ( id . type !== 'ArrayPattern' && id . type !== 'Identifier' ) return
500- const tupleTypes : FlowTypeKind [ ] = [
501- j . genericTypeAnnotation (
502- j . identifier ( mutationFunction . id . name ) ,
503- null
504- ) ,
505- ]
506- if ( data && id . type === 'ArrayPattern' && id . elements . length > 1 )
507- tupleTypes . push ( mutationResultAnnotation ( data ) . typeAnnotation )
508- // https://github.com/benjamn/ast-types/issues/372
509- ; ( id as any ) . typeAnnotation = j . typeAnnotation (
510- j . tupleTypeAnnotation ( tupleTypes )
511- )
520+ if ( useFunctionTypeArguments ) {
521+ ; ( path . node . init as any ) . typeArguments = makeFunctionTypeArguments (
522+ data ,
523+ variables
524+ )
525+ } else {
526+ if ( id . type !== 'ArrayPattern' && id . type !== 'Identifier' ) return
527+ const tupleTypes : FlowTypeKind [ ] = [
528+ j . genericTypeAnnotation (
529+ j . identifier ( mutationFunction . id . name ) ,
530+ null
531+ ) ,
532+ ]
533+ if ( data && id . type === 'ArrayPattern' && id . elements . length > 1 )
534+ tupleTypes . push ( mutationResultAnnotation ( data ) . typeAnnotation )
535+ // https://github.com/benjamn/ast-types/issues/372
536+ ; ( id as any ) . typeAnnotation = j . typeAnnotation (
537+ j . tupleTypeAnnotation ( tupleTypes )
538+ )
539+ }
512540 } )
513541 }
514542
@@ -531,38 +559,48 @@ export default function graphqlTypegenCore(
531559 const { data, variables } =
532560 onlyValue ( generatedTypes . subscription ) || { }
533561 if ( ! data ) return
534- if (
535- path . node . id . type === 'Identifier' ||
536- path . node . id . type === 'ObjectPattern'
537- ) {
538- path . node . id . typeAnnotation = subscriptionResultAnnotation (
562+ if ( useFunctionTypeArguments ) {
563+ ; ( path . node . init as any ) . typeArguments = makeFunctionTypeArguments (
539564 data ,
540565 variables
541566 )
542- }
543- if ( path . node . init ?. type !== 'CallExpression' ) return
544- const options = path . node . init . arguments [ 1 ]
545- if ( variables && options && options . type === 'ObjectExpression' ) {
546- const variablesProp = options . properties . find (
547- p =>
548- p . type !== 'SpreadElement' &&
549- p . type !== 'SpreadProperty' &&
550- p . key . type === 'Identifier' &&
551- p . key . name === 'variables'
552- )
567+ } else {
553568 if (
554- variablesProp &&
555- variablesProp . type !== 'SpreadElement' &&
556- variablesProp . type !== 'SpreadProperty' &&
557- variablesProp . type !== 'ObjectMethod'
569+ path . node . id . type === 'Identifier' ||
570+ path . node . id . type === 'ObjectPattern'
558571 ) {
559- variablesProp . value = typeCast (
560- variablesProp . value as ExpressionKind ,
561- j . typeAnnotation (
562- j . genericTypeAnnotation ( j . identifier ( variables . id . name ) , null )
563- )
572+ path . node . id . typeAnnotation = subscriptionResultAnnotation (
573+ data ,
574+ variables
564575 )
565576 }
577+ if ( path . node . init ?. type !== 'CallExpression' ) return
578+ const options = path . node . init . arguments [ 1 ]
579+ if ( variables && options && options . type === 'ObjectExpression' ) {
580+ const variablesProp = options . properties . find (
581+ p =>
582+ p . type !== 'SpreadElement' &&
583+ p . type !== 'SpreadProperty' &&
584+ p . key . type === 'Identifier' &&
585+ p . key . name === 'variables'
586+ )
587+ if (
588+ variablesProp &&
589+ variablesProp . type !== 'SpreadElement' &&
590+ variablesProp . type !== 'SpreadProperty' &&
591+ variablesProp . type !== 'ObjectMethod'
592+ ) {
593+ variablesProp . value = typeCast (
594+ variablesProp . value as ExpressionKind ,
595+ j . typeAnnotation (
596+ j . genericTypeAnnotation (
597+ j . identifier ( variables . id . name ) ,
598+ null
599+ )
600+ )
601+ )
602+ }
603+ }
566604 }
567605 } )
568606 }
0 commit comments