@graphql-codegen/visitor-plugin-common 6.0.0-alpha-20250509134235-30ac8930f49f44ab10e6b7dcdd7f12a67bfa9fc4 → 6.0.0-alpha-20250529121049-5e08c758900167a8eaee6ff178599c2b990bf21d

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.
@@ -328,7 +328,7 @@ class BaseResolversVisitor extends base_visitor_js_1.BaseVisitor {
328
328
  * Function to generate the types of Abstract Type Members i.e. Union Members or Interface Implementing Types
329
329
  */
330
330
  getAbstractMembersType({ typeName, memberTypes, isTypenameNonOptional, }) {
331
- const result = memberTypes
331
+ const members = memberTypes
332
332
  .map(type => {
333
333
  const isTypeMapped = this.config.mappers[type.name];
334
334
  // 1. If mapped without placehoder, just use it without doing extra checks
@@ -367,8 +367,12 @@ class BaseResolversVisitor extends base_visitor_js_1.BaseVisitor {
367
367
  .map(({ typename, typeValue }) => {
368
368
  const nonOptionalTypenameModifier = isTypenameNonOptional ? ` & { __typename: '${typename}' }` : '';
369
369
  return `( ${typeValue}${nonOptionalTypenameModifier} )`; // Must wrap every type in explicit "( )" to separate them
370
- })
371
- .join(' | ') || 'never';
370
+ });
371
+ const result = members.length === 0
372
+ ? 'never'
373
+ : members.length > 1
374
+ ? `\n | ${members.map(m => m.replace(/\n/g, '\n ')).join('\n | ')}\n `
375
+ : members.join(' | ');
372
376
  return result;
373
377
  }
374
378
  createFieldContextTypeMap() {
@@ -599,6 +603,9 @@ class BaseResolversVisitor extends base_visitor_js_1.BaseVisitor {
599
603
  }
600
604
  return '';
601
605
  }
606
+ // FIXME: this Name method causes a lot of type inconsistencies
607
+ // because the type of nodes no longer matches the `graphql-js` types
608
+ // So, we should update this and remove any relevant `as any as string` or `as unknown as string`
602
609
  Name(node) {
603
610
  return node.value;
604
611
  }
@@ -640,88 +647,96 @@ class BaseResolversVisitor extends base_visitor_js_1.BaseVisitor {
640
647
  FieldDefinition(node, key, parent) {
641
648
  const hasArguments = node.arguments && node.arguments.length > 0;
642
649
  const declarationKind = 'type';
643
- return (parentName, avoidResolverOptionals) => {
644
- const original = parent[key];
645
- const parentType = this.schema.getType(parentName);
646
- const meta = {};
647
- if (this._federation.skipField({ fieldNode: original, parentType })) {
648
- return { value: null, meta };
649
- }
650
- const contextType = this.getContextType(parentName, node);
651
- let argsType = hasArguments
652
- ? this.convertName(parentName +
653
- (this.config.addUnderscoreToArgsType ? '_' : '') +
654
- this.convertName(node.name, {
655
- useTypesPrefix: false,
656
- useTypesSuffix: false,
657
- }) +
658
- 'Args', {
659
- useTypesPrefix: true,
660
- }, true)
661
- : null;
662
- const avoidInputsOptionals = this.config.avoidOptionals.inputValue;
663
- if (argsType !== null) {
664
- const argsToForceRequire = original.arguments.filter(arg => !!arg.defaultValue || arg.type.kind === 'NonNullType');
665
- if (argsToForceRequire.length > 0) {
666
- argsType = this.applyRequireFields(argsType, argsToForceRequire);
650
+ const original = parent[key];
651
+ return {
652
+ node: original,
653
+ printContent: (parentNode, avoidResolverOptionals) => {
654
+ const parentName = parentNode.name;
655
+ const parentType = this.schema.getType(parentName);
656
+ const meta = {};
657
+ const typeName = node.name;
658
+ const fieldsToGenerate = this._federation.findFieldNodesToGenerate({ node: parentNode });
659
+ const shouldGenerateField = fieldsToGenerate.some(field => field.name.value === typeName) ||
660
+ this._federation.isResolveReferenceField(node);
661
+ if (!shouldGenerateField) {
662
+ return { value: null, meta };
667
663
  }
668
- else if (original.arguments.length > 0 && avoidInputsOptionals !== true) {
669
- argsType = this.applyOptionalFields(argsType, original.arguments);
664
+ const contextType = this.getContextType(parentName, node);
665
+ let argsType = hasArguments
666
+ ? this.convertName(parentName +
667
+ (this.config.addUnderscoreToArgsType ? '_' : '') +
668
+ this.convertName(typeName, {
669
+ useTypesPrefix: false,
670
+ useTypesSuffix: false,
671
+ }) +
672
+ 'Args', {
673
+ useTypesPrefix: true,
674
+ }, true)
675
+ : null;
676
+ const avoidInputsOptionals = this.config.avoidOptionals.inputValue;
677
+ if (argsType !== null) {
678
+ const argsToForceRequire = original.arguments.filter(arg => !!arg.defaultValue || arg.type.kind === 'NonNullType');
679
+ if (argsToForceRequire.length > 0) {
680
+ argsType = this.applyRequireFields(argsType, argsToForceRequire);
681
+ }
682
+ else if (original.arguments.length > 0 && avoidInputsOptionals !== true) {
683
+ argsType = this.applyOptionalFields(argsType, original.arguments);
684
+ }
670
685
  }
671
- }
672
- const parentTypeSignature = this._federation.transformFieldParentType({
673
- fieldNode: original,
674
- parentType,
675
- parentTypeSignature: this.getParentTypeForSignature(node),
676
- federationTypeSignature: 'FederationType',
677
- });
678
- const { mappedTypeKey, resolverType } = (() => {
679
- const baseType = (0, utils_js_1.getBaseTypeNode)(original.type);
680
- const realType = baseType.name.value;
681
- const typeToUse = this.getTypeToUse(realType);
682
- /**
683
- * Turns GraphQL type to TypeScript types (`mappedType`) e.g.
684
- * - String! -> ResolversTypes['String']>
685
- * - String -> Maybe<ResolversTypes['String']>
686
- * - [String] -> Maybe<Array<Maybe<ResolversTypes['String']>>>
687
- * - [String!]! -> Array<ResolversTypes['String']>
688
- */
689
- const mappedType = this._variablesTransformer.wrapAstTypeWithModifiers(typeToUse, original.type);
690
- const subscriptionType = this._schema.getSubscriptionType();
691
- const isSubscriptionType = subscriptionType && subscriptionType.name === parentName;
692
- if (isSubscriptionType) {
686
+ const parentTypeSignature = this._federation.transformFieldParentType({
687
+ fieldNode: original,
688
+ parentType,
689
+ parentTypeSignature: this.getParentTypeForSignature(node),
690
+ federationTypeSignature: 'FederationType',
691
+ });
692
+ const { mappedTypeKey, resolverType } = (() => {
693
+ const baseType = (0, utils_js_1.getBaseTypeNode)(original.type);
694
+ const realType = baseType.name.value;
695
+ const typeToUse = this.getTypeToUse(realType);
696
+ /**
697
+ * Turns GraphQL type to TypeScript types (`mappedType`) e.g.
698
+ * - String! -> ResolversTypes['String']>
699
+ * - String -> Maybe<ResolversTypes['String']>
700
+ * - [String] -> Maybe<Array<Maybe<ResolversTypes['String']>>>
701
+ * - [String!]! -> Array<ResolversTypes['String']>
702
+ */
703
+ const mappedType = this._variablesTransformer.wrapAstTypeWithModifiers(typeToUse, original.type);
704
+ const subscriptionType = this._schema.getSubscriptionType();
705
+ const isSubscriptionType = subscriptionType && subscriptionType.name === parentName;
706
+ if (isSubscriptionType) {
707
+ return {
708
+ mappedTypeKey: `${mappedType}, "${typeName}"`,
709
+ resolverType: 'SubscriptionResolver',
710
+ };
711
+ }
712
+ const directiveMappings = node.directives
713
+ ?.map(directive => this._directiveResolverMappings[directive.name])
714
+ .filter(Boolean)
715
+ .reverse() ?? [];
693
716
  return {
694
- mappedTypeKey: `${mappedType}, "${node.name}"`,
695
- resolverType: 'SubscriptionResolver',
717
+ mappedTypeKey: mappedType,
718
+ resolverType: directiveMappings[0] ?? 'Resolver',
696
719
  };
720
+ })();
721
+ const signature = {
722
+ name: typeName,
723
+ modifier: avoidResolverOptionals ? '' : '?',
724
+ type: resolverType,
725
+ genericTypes: [mappedTypeKey, parentTypeSignature, contextType, argsType].filter(f => f),
726
+ };
727
+ if (this._federation.isResolveReferenceField(node)) {
728
+ if (!this._federation.getMeta()[parentType.name].hasResolveReference) {
729
+ return { value: '', meta };
730
+ }
731
+ signature.type = 'ReferenceResolver';
732
+ signature.genericTypes = [mappedTypeKey, parentTypeSignature, contextType];
733
+ meta.federation = { isResolveReference: true };
697
734
  }
698
- const directiveMappings = node.directives
699
- ?.map(directive => this._directiveResolverMappings[directive.name])
700
- .filter(Boolean)
701
- .reverse() ?? [];
702
735
  return {
703
- mappedTypeKey: mappedType,
704
- resolverType: directiveMappings[0] ?? 'Resolver',
736
+ value: (0, utils_js_1.indent)(`${signature.name}${signature.modifier}: ${signature.type}<${signature.genericTypes.join(', ')}>${this.getPunctuation(declarationKind)}`),
737
+ meta,
705
738
  };
706
- })();
707
- const signature = {
708
- name: node.name,
709
- modifier: avoidResolverOptionals ? '' : '?',
710
- type: resolverType,
711
- genericTypes: [mappedTypeKey, parentTypeSignature, contextType, argsType].filter(f => f),
712
- };
713
- if (this._federation.isResolveReferenceField(node)) {
714
- if (!this._federation.getMeta()[parentType.name].hasResolveReference) {
715
- return { value: '', meta };
716
- }
717
- signature.type = 'ReferenceResolver';
718
- signature.genericTypes = [mappedTypeKey, parentTypeSignature, contextType];
719
- meta.federation = { isResolveReference: true };
720
- }
721
- return {
722
- value: (0, utils_js_1.indent)(`${signature.name}${signature.modifier}: ${signature.type}<${signature.genericTypes.join(', ')}>${this.getPunctuation(declarationKind)}`),
723
- meta,
724
- };
739
+ },
725
740
  };
726
741
  }
727
742
  getFieldContextType(parentName, node) {
@@ -782,11 +797,15 @@ class BaseResolversVisitor extends base_visitor_js_1.BaseVisitor {
782
797
  return `Partial<${argsType}>`;
783
798
  }
784
799
  ObjectTypeDefinition(node) {
800
+ const typeName = node.name;
801
+ const fieldsToGenerate = this._federation.findFieldNodesToGenerate({ node });
802
+ if (fieldsToGenerate.length === 0) {
803
+ return null;
804
+ }
785
805
  const declarationKind = 'type';
786
806
  const name = this.convertName(node, {
787
807
  suffix: this.config.resolverTypeSuffix,
788
808
  });
789
- const typeName = node.name;
790
809
  const parentType = this.getParentTypeToUse(typeName);
791
810
  const rootType = (() => {
792
811
  if (this.schema.getQueryType()?.name === typeName) {
@@ -800,15 +819,20 @@ class BaseResolversVisitor extends base_visitor_js_1.BaseVisitor {
800
819
  }
801
820
  return false;
802
821
  })();
803
- const fieldsContent = node.fields.map(f => {
804
- return f(typeName, (rootType === 'query' && this.config.avoidOptionals.query) ||
822
+ const fieldsContent = node.fields
823
+ .map(({ printContent }) => {
824
+ return printContent(node, (rootType === 'query' && this.config.avoidOptionals.query) ||
805
825
  (rootType === 'mutation' && this.config.avoidOptionals.mutation) ||
806
826
  (rootType === 'subscription' && this.config.avoidOptionals.subscription) ||
807
827
  (rootType === false && this.config.avoidOptionals.resolvers)).value;
808
- });
828
+ })
829
+ .filter(v => v);
809
830
  if (!rootType && this._parsedSchemaMeta.typesWithIsTypeOf[typeName]) {
810
831
  fieldsContent.push((0, utils_js_1.indent)(`${this.config.internalResolversPrefix}isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>${this.getPunctuation(declarationKind)}`));
811
832
  }
833
+ if (fieldsContent.length === 0) {
834
+ return null;
835
+ }
812
836
  const genericTypes = [
813
837
  `ContextType = ${this.config.contextType.type}`,
814
838
  this.transformParentGenericType(parentType),
@@ -968,7 +992,7 @@ class BaseResolversVisitor extends base_visitor_js_1.BaseVisitor {
968
992
  ];
969
993
  // An Interface in Federation may have the additional __resolveReference resolver, if resolvable.
970
994
  // So, we filter out the normal fields declared on the Interface and add the __resolveReference resolver.
971
- const fields = node.fields.map(f => f(typeName, this.config.avoidOptionals.resolvers));
995
+ const fields = node.fields.map(({ printContent }) => printContent(node, this.config.avoidOptionals.resolvers));
972
996
  for (const field of fields) {
973
997
  if (field.meta.federation?.isResolveReference) {
974
998
  blockFields.push(field.value);
@@ -589,7 +589,7 @@ class SelectionSetToObject {
589
589
  .join(' & ')),
590
590
  this.getEmptyObjectTypeString(mustAddEmptyObject),
591
591
  ].filter(Boolean);
592
- const content = typeParts.join(' | ');
592
+ const content = formatUnion(typeParts);
593
593
  if (typeParts.length > 1 && this._config.extractAllFieldsToTypes) {
594
594
  return {
595
595
  mergedTypeString: fieldName,
@@ -662,7 +662,7 @@ class SelectionSetToObject {
662
662
  .export()
663
663
  .asKind('type')
664
664
  .withName(mergedTypeString)
665
- .withContent(subTypes.map(t => t.name).join(' | ')).string,
665
+ .withContent(formatUnion(subTypes.map(t => t.name))).string,
666
666
  ].join('\n');
667
667
  }
668
668
  buildFragmentTypeName(name, suffix, typeName = '') {
@@ -678,3 +678,9 @@ class SelectionSetToObject {
678
678
  }
679
679
  }
680
680
  exports.SelectionSetToObject = SelectionSetToObject;
681
+ function formatUnion(members) {
682
+ if (members.length > 1) {
683
+ return `\n | ${members.map(m => m.replace(/\n/g, '\n ')).join('\n | ')}\n`;
684
+ }
685
+ return members.join(' | ');
686
+ }
@@ -324,7 +324,7 @@ export class BaseResolversVisitor extends BaseVisitor {
324
324
  * Function to generate the types of Abstract Type Members i.e. Union Members or Interface Implementing Types
325
325
  */
326
326
  getAbstractMembersType({ typeName, memberTypes, isTypenameNonOptional, }) {
327
- const result = memberTypes
327
+ const members = memberTypes
328
328
  .map(type => {
329
329
  const isTypeMapped = this.config.mappers[type.name];
330
330
  // 1. If mapped without placehoder, just use it without doing extra checks
@@ -363,8 +363,12 @@ export class BaseResolversVisitor extends BaseVisitor {
363
363
  .map(({ typename, typeValue }) => {
364
364
  const nonOptionalTypenameModifier = isTypenameNonOptional ? ` & { __typename: '${typename}' }` : '';
365
365
  return `( ${typeValue}${nonOptionalTypenameModifier} )`; // Must wrap every type in explicit "( )" to separate them
366
- })
367
- .join(' | ') || 'never';
366
+ });
367
+ const result = members.length === 0
368
+ ? 'never'
369
+ : members.length > 1
370
+ ? `\n | ${members.map(m => m.replace(/\n/g, '\n ')).join('\n | ')}\n `
371
+ : members.join(' | ');
368
372
  return result;
369
373
  }
370
374
  createFieldContextTypeMap() {
@@ -595,6 +599,9 @@ export class BaseResolversVisitor extends BaseVisitor {
595
599
  }
596
600
  return '';
597
601
  }
602
+ // FIXME: this Name method causes a lot of type inconsistencies
603
+ // because the type of nodes no longer matches the `graphql-js` types
604
+ // So, we should update this and remove any relevant `as any as string` or `as unknown as string`
598
605
  Name(node) {
599
606
  return node.value;
600
607
  }
@@ -636,88 +643,96 @@ export class BaseResolversVisitor extends BaseVisitor {
636
643
  FieldDefinition(node, key, parent) {
637
644
  const hasArguments = node.arguments && node.arguments.length > 0;
638
645
  const declarationKind = 'type';
639
- return (parentName, avoidResolverOptionals) => {
640
- const original = parent[key];
641
- const parentType = this.schema.getType(parentName);
642
- const meta = {};
643
- if (this._federation.skipField({ fieldNode: original, parentType })) {
644
- return { value: null, meta };
645
- }
646
- const contextType = this.getContextType(parentName, node);
647
- let argsType = hasArguments
648
- ? this.convertName(parentName +
649
- (this.config.addUnderscoreToArgsType ? '_' : '') +
650
- this.convertName(node.name, {
651
- useTypesPrefix: false,
652
- useTypesSuffix: false,
653
- }) +
654
- 'Args', {
655
- useTypesPrefix: true,
656
- }, true)
657
- : null;
658
- const avoidInputsOptionals = this.config.avoidOptionals.inputValue;
659
- if (argsType !== null) {
660
- const argsToForceRequire = original.arguments.filter(arg => !!arg.defaultValue || arg.type.kind === 'NonNullType');
661
- if (argsToForceRequire.length > 0) {
662
- argsType = this.applyRequireFields(argsType, argsToForceRequire);
646
+ const original = parent[key];
647
+ return {
648
+ node: original,
649
+ printContent: (parentNode, avoidResolverOptionals) => {
650
+ const parentName = parentNode.name;
651
+ const parentType = this.schema.getType(parentName);
652
+ const meta = {};
653
+ const typeName = node.name;
654
+ const fieldsToGenerate = this._federation.findFieldNodesToGenerate({ node: parentNode });
655
+ const shouldGenerateField = fieldsToGenerate.some(field => field.name.value === typeName) ||
656
+ this._federation.isResolveReferenceField(node);
657
+ if (!shouldGenerateField) {
658
+ return { value: null, meta };
663
659
  }
664
- else if (original.arguments.length > 0 && avoidInputsOptionals !== true) {
665
- argsType = this.applyOptionalFields(argsType, original.arguments);
660
+ const contextType = this.getContextType(parentName, node);
661
+ let argsType = hasArguments
662
+ ? this.convertName(parentName +
663
+ (this.config.addUnderscoreToArgsType ? '_' : '') +
664
+ this.convertName(typeName, {
665
+ useTypesPrefix: false,
666
+ useTypesSuffix: false,
667
+ }) +
668
+ 'Args', {
669
+ useTypesPrefix: true,
670
+ }, true)
671
+ : null;
672
+ const avoidInputsOptionals = this.config.avoidOptionals.inputValue;
673
+ if (argsType !== null) {
674
+ const argsToForceRequire = original.arguments.filter(arg => !!arg.defaultValue || arg.type.kind === 'NonNullType');
675
+ if (argsToForceRequire.length > 0) {
676
+ argsType = this.applyRequireFields(argsType, argsToForceRequire);
677
+ }
678
+ else if (original.arguments.length > 0 && avoidInputsOptionals !== true) {
679
+ argsType = this.applyOptionalFields(argsType, original.arguments);
680
+ }
666
681
  }
667
- }
668
- const parentTypeSignature = this._federation.transformFieldParentType({
669
- fieldNode: original,
670
- parentType,
671
- parentTypeSignature: this.getParentTypeForSignature(node),
672
- federationTypeSignature: 'FederationType',
673
- });
674
- const { mappedTypeKey, resolverType } = (() => {
675
- const baseType = getBaseTypeNode(original.type);
676
- const realType = baseType.name.value;
677
- const typeToUse = this.getTypeToUse(realType);
678
- /**
679
- * Turns GraphQL type to TypeScript types (`mappedType`) e.g.
680
- * - String! -> ResolversTypes['String']>
681
- * - String -> Maybe<ResolversTypes['String']>
682
- * - [String] -> Maybe<Array<Maybe<ResolversTypes['String']>>>
683
- * - [String!]! -> Array<ResolversTypes['String']>
684
- */
685
- const mappedType = this._variablesTransformer.wrapAstTypeWithModifiers(typeToUse, original.type);
686
- const subscriptionType = this._schema.getSubscriptionType();
687
- const isSubscriptionType = subscriptionType && subscriptionType.name === parentName;
688
- if (isSubscriptionType) {
682
+ const parentTypeSignature = this._federation.transformFieldParentType({
683
+ fieldNode: original,
684
+ parentType,
685
+ parentTypeSignature: this.getParentTypeForSignature(node),
686
+ federationTypeSignature: 'FederationType',
687
+ });
688
+ const { mappedTypeKey, resolverType } = (() => {
689
+ const baseType = getBaseTypeNode(original.type);
690
+ const realType = baseType.name.value;
691
+ const typeToUse = this.getTypeToUse(realType);
692
+ /**
693
+ * Turns GraphQL type to TypeScript types (`mappedType`) e.g.
694
+ * - String! -> ResolversTypes['String']>
695
+ * - String -> Maybe<ResolversTypes['String']>
696
+ * - [String] -> Maybe<Array<Maybe<ResolversTypes['String']>>>
697
+ * - [String!]! -> Array<ResolversTypes['String']>
698
+ */
699
+ const mappedType = this._variablesTransformer.wrapAstTypeWithModifiers(typeToUse, original.type);
700
+ const subscriptionType = this._schema.getSubscriptionType();
701
+ const isSubscriptionType = subscriptionType && subscriptionType.name === parentName;
702
+ if (isSubscriptionType) {
703
+ return {
704
+ mappedTypeKey: `${mappedType}, "${typeName}"`,
705
+ resolverType: 'SubscriptionResolver',
706
+ };
707
+ }
708
+ const directiveMappings = node.directives
709
+ ?.map(directive => this._directiveResolverMappings[directive.name])
710
+ .filter(Boolean)
711
+ .reverse() ?? [];
689
712
  return {
690
- mappedTypeKey: `${mappedType}, "${node.name}"`,
691
- resolverType: 'SubscriptionResolver',
713
+ mappedTypeKey: mappedType,
714
+ resolverType: directiveMappings[0] ?? 'Resolver',
692
715
  };
716
+ })();
717
+ const signature = {
718
+ name: typeName,
719
+ modifier: avoidResolverOptionals ? '' : '?',
720
+ type: resolverType,
721
+ genericTypes: [mappedTypeKey, parentTypeSignature, contextType, argsType].filter(f => f),
722
+ };
723
+ if (this._federation.isResolveReferenceField(node)) {
724
+ if (!this._federation.getMeta()[parentType.name].hasResolveReference) {
725
+ return { value: '', meta };
726
+ }
727
+ signature.type = 'ReferenceResolver';
728
+ signature.genericTypes = [mappedTypeKey, parentTypeSignature, contextType];
729
+ meta.federation = { isResolveReference: true };
693
730
  }
694
- const directiveMappings = node.directives
695
- ?.map(directive => this._directiveResolverMappings[directive.name])
696
- .filter(Boolean)
697
- .reverse() ?? [];
698
731
  return {
699
- mappedTypeKey: mappedType,
700
- resolverType: directiveMappings[0] ?? 'Resolver',
732
+ value: indent(`${signature.name}${signature.modifier}: ${signature.type}<${signature.genericTypes.join(', ')}>${this.getPunctuation(declarationKind)}`),
733
+ meta,
701
734
  };
702
- })();
703
- const signature = {
704
- name: node.name,
705
- modifier: avoidResolverOptionals ? '' : '?',
706
- type: resolverType,
707
- genericTypes: [mappedTypeKey, parentTypeSignature, contextType, argsType].filter(f => f),
708
- };
709
- if (this._federation.isResolveReferenceField(node)) {
710
- if (!this._federation.getMeta()[parentType.name].hasResolveReference) {
711
- return { value: '', meta };
712
- }
713
- signature.type = 'ReferenceResolver';
714
- signature.genericTypes = [mappedTypeKey, parentTypeSignature, contextType];
715
- meta.federation = { isResolveReference: true };
716
- }
717
- return {
718
- value: indent(`${signature.name}${signature.modifier}: ${signature.type}<${signature.genericTypes.join(', ')}>${this.getPunctuation(declarationKind)}`),
719
- meta,
720
- };
735
+ },
721
736
  };
722
737
  }
723
738
  getFieldContextType(parentName, node) {
@@ -778,11 +793,15 @@ export class BaseResolversVisitor extends BaseVisitor {
778
793
  return `Partial<${argsType}>`;
779
794
  }
780
795
  ObjectTypeDefinition(node) {
796
+ const typeName = node.name;
797
+ const fieldsToGenerate = this._federation.findFieldNodesToGenerate({ node });
798
+ if (fieldsToGenerate.length === 0) {
799
+ return null;
800
+ }
781
801
  const declarationKind = 'type';
782
802
  const name = this.convertName(node, {
783
803
  suffix: this.config.resolverTypeSuffix,
784
804
  });
785
- const typeName = node.name;
786
805
  const parentType = this.getParentTypeToUse(typeName);
787
806
  const rootType = (() => {
788
807
  if (this.schema.getQueryType()?.name === typeName) {
@@ -796,15 +815,20 @@ export class BaseResolversVisitor extends BaseVisitor {
796
815
  }
797
816
  return false;
798
817
  })();
799
- const fieldsContent = node.fields.map(f => {
800
- return f(typeName, (rootType === 'query' && this.config.avoidOptionals.query) ||
818
+ const fieldsContent = node.fields
819
+ .map(({ printContent }) => {
820
+ return printContent(node, (rootType === 'query' && this.config.avoidOptionals.query) ||
801
821
  (rootType === 'mutation' && this.config.avoidOptionals.mutation) ||
802
822
  (rootType === 'subscription' && this.config.avoidOptionals.subscription) ||
803
823
  (rootType === false && this.config.avoidOptionals.resolvers)).value;
804
- });
824
+ })
825
+ .filter(v => v);
805
826
  if (!rootType && this._parsedSchemaMeta.typesWithIsTypeOf[typeName]) {
806
827
  fieldsContent.push(indent(`${this.config.internalResolversPrefix}isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>${this.getPunctuation(declarationKind)}`));
807
828
  }
829
+ if (fieldsContent.length === 0) {
830
+ return null;
831
+ }
808
832
  const genericTypes = [
809
833
  `ContextType = ${this.config.contextType.type}`,
810
834
  this.transformParentGenericType(parentType),
@@ -964,7 +988,7 @@ export class BaseResolversVisitor extends BaseVisitor {
964
988
  ];
965
989
  // An Interface in Federation may have the additional __resolveReference resolver, if resolvable.
966
990
  // So, we filter out the normal fields declared on the Interface and add the __resolveReference resolver.
967
- const fields = node.fields.map(f => f(typeName, this.config.avoidOptionals.resolvers));
991
+ const fields = node.fields.map(({ printContent }) => printContent(node, this.config.avoidOptionals.resolvers));
968
992
  for (const field of fields) {
969
993
  if (field.meta.federation?.isResolveReference) {
970
994
  blockFields.push(field.value);
@@ -585,7 +585,7 @@ export class SelectionSetToObject {
585
585
  .join(' & ')),
586
586
  this.getEmptyObjectTypeString(mustAddEmptyObject),
587
587
  ].filter(Boolean);
588
- const content = typeParts.join(' | ');
588
+ const content = formatUnion(typeParts);
589
589
  if (typeParts.length > 1 && this._config.extractAllFieldsToTypes) {
590
590
  return {
591
591
  mergedTypeString: fieldName,
@@ -658,7 +658,7 @@ export class SelectionSetToObject {
658
658
  .export()
659
659
  .asKind('type')
660
660
  .withName(mergedTypeString)
661
- .withContent(subTypes.map(t => t.name).join(' | ')).string,
661
+ .withContent(formatUnion(subTypes.map(t => t.name))).string,
662
662
  ].join('\n');
663
663
  }
664
664
  buildFragmentTypeName(name, suffix, typeName = '') {
@@ -673,3 +673,9 @@ export class SelectionSetToObject {
673
673
  return operationTypes.includes(typeName) ? parentName : `${parentName}_${typeName}`;
674
674
  }
675
675
  }
676
+ function formatUnion(members) {
677
+ if (members.length > 1) {
678
+ return `\n | ${members.map(m => m.replace(/\n/g, '\n ')).join('\n | ')}\n`;
679
+ }
680
+ return members.join(' | ');
681
+ }
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@graphql-codegen/visitor-plugin-common",
3
- "version": "6.0.0-alpha-20250509134235-30ac8930f49f44ab10e6b7dcdd7f12a67bfa9fc4",
3
+ "version": "6.0.0-alpha-20250529121049-5e08c758900167a8eaee6ff178599c2b990bf21d",
4
4
  "peerDependencies": {
5
5
  "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
6
6
  },
7
7
  "dependencies": {
8
8
  "@graphql-tools/optimize": "^2.0.0",
9
- "@graphql-codegen/plugin-helpers": "6.0.0-alpha-20250509134235-30ac8930f49f44ab10e6b7dcdd7f12a67bfa9fc4",
9
+ "@graphql-codegen/plugin-helpers": "6.0.0-alpha-20250529121049-5e08c758900167a8eaee6ff178599c2b990bf21d",
10
10
  "@graphql-tools/relay-operation-optimizer": "^7.0.0",
11
11
  "@graphql-tools/utils": "^10.0.0",
12
12
  "auto-bind": "~4.0.0",
@@ -31,7 +31,11 @@ export interface ParsedResolversConfig extends ParsedConfig {
31
31
  resolversNonOptionalTypename: ResolversNonOptionalTypenameConfig;
32
32
  avoidCheckingAbstractTypesRecursively: boolean;
33
33
  }
34
- type FieldDefinitionPrintFn = (parentName: string, avoidResolverOptionals: boolean) => {
34
+ export interface FieldDefinitionResult {
35
+ node: FieldDefinitionNode;
36
+ printContent: FieldDefinitionPrintFn;
37
+ }
38
+ type FieldDefinitionPrintFn = (parentNode: ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode, avoidResolverOptionals: boolean) => {
35
39
  value: string | null;
36
40
  meta: {
37
41
  federation?: {
@@ -756,13 +760,13 @@ export declare class BaseResolversVisitor<TRawConfig extends RawResolversConfig
756
760
  protected getParentTypeToUse(name: string): string;
757
761
  protected getParentTypeForSignature(_node: FieldDefinitionNode): string;
758
762
  protected transformParentGenericType(parentType: string): string;
759
- FieldDefinition(node: FieldDefinitionNode, key: string | number, parent: any): FieldDefinitionPrintFn;
763
+ FieldDefinition(node: FieldDefinitionNode, key: string | number, parent: any): FieldDefinitionResult;
760
764
  private getFieldContextType;
761
765
  private getContextType;
762
766
  private parseSchemaMeta;
763
767
  protected applyRequireFields(argsType: string, fields: InputValueDefinitionNode[]): string;
764
768
  protected applyOptionalFields(argsType: string, _fields: readonly InputValueDefinitionNode[]): string;
765
- ObjectTypeDefinition(node: ObjectTypeDefinitionNode): string;
769
+ ObjectTypeDefinition(node: ObjectTypeDefinitionNode): string | null;
766
770
  UnionTypeDefinition(node: UnionTypeDefinitionNode, key: string | number, parent: any): string;
767
771
  ScalarTypeDefinition(node: ScalarTypeDefinitionNode): string;
768
772
  DirectiveDefinition(node: DirectiveDefinitionNode, key: string | number, parent: any): string;
@@ -31,7 +31,11 @@ export interface ParsedResolversConfig extends ParsedConfig {
31
31
  resolversNonOptionalTypename: ResolversNonOptionalTypenameConfig;
32
32
  avoidCheckingAbstractTypesRecursively: boolean;
33
33
  }
34
- type FieldDefinitionPrintFn = (parentName: string, avoidResolverOptionals: boolean) => {
34
+ export interface FieldDefinitionResult {
35
+ node: FieldDefinitionNode;
36
+ printContent: FieldDefinitionPrintFn;
37
+ }
38
+ type FieldDefinitionPrintFn = (parentNode: ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode, avoidResolverOptionals: boolean) => {
35
39
  value: string | null;
36
40
  meta: {
37
41
  federation?: {
@@ -756,13 +760,13 @@ export declare class BaseResolversVisitor<TRawConfig extends RawResolversConfig
756
760
  protected getParentTypeToUse(name: string): string;
757
761
  protected getParentTypeForSignature(_node: FieldDefinitionNode): string;
758
762
  protected transformParentGenericType(parentType: string): string;
759
- FieldDefinition(node: FieldDefinitionNode, key: string | number, parent: any): FieldDefinitionPrintFn;
763
+ FieldDefinition(node: FieldDefinitionNode, key: string | number, parent: any): FieldDefinitionResult;
760
764
  private getFieldContextType;
761
765
  private getContextType;
762
766
  private parseSchemaMeta;
763
767
  protected applyRequireFields(argsType: string, fields: InputValueDefinitionNode[]): string;
764
768
  protected applyOptionalFields(argsType: string, _fields: readonly InputValueDefinitionNode[]): string;
765
- ObjectTypeDefinition(node: ObjectTypeDefinitionNode): string;
769
+ ObjectTypeDefinition(node: ObjectTypeDefinitionNode): string | null;
766
770
  UnionTypeDefinition(node: UnionTypeDefinitionNode, key: string | number, parent: any): string;
767
771
  ScalarTypeDefinition(node: ScalarTypeDefinitionNode): string;
768
772
  DirectiveDefinition(node: DirectiveDefinitionNode, key: string | number, parent: any): string;