@graphql-codegen/visitor-plugin-common 7.2.1-alpha-20260719125849-4e20a28d5fee4dafc8a6cf0e22a03eedfd6ab3ff → 7.2.1

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.
@@ -73,10 +73,7 @@ class SelectionSetToObject {
73
73
  // fragment (using @defer).
74
74
  const fieldsWithFragmentDirectives = fields.map(field => ({
75
75
  ...field,
76
- // A field may already carry `fragmentDirectives` from an enclosing
77
- // conditional fragment spread; keep those in addition to the
78
- // directives on this inline fragment, instead of overwriting them.
79
- fragmentDirectives: [...(field.fragmentDirectives || []), ...(directives || [])],
76
+ fragmentDirectives: directives,
80
77
  }));
81
78
  if ((0, graphql_1.isObjectType)(typeOnSchema)) {
82
79
  this._appendToTypeMap(types, typeOnSchema.name, fieldsWithFragmentDirectives);
@@ -521,7 +518,7 @@ class SelectionSetToObject {
521
518
  selectionNodes = [...selectionNodes];
522
519
  let inlineFragmentConditional = false;
523
520
  for (const selectionNode of selectionNodes) {
524
- // 1. Handle Field or Directives selection nodes
521
+ // 1. Handle Field or Directtives selection nodes
525
522
  if ('kind' in selectionNode) {
526
523
  if (selectionNode.kind === graphql_1.Kind.FIELD) {
527
524
  if (selectionNode.selectionSet) {
@@ -597,9 +594,6 @@ class SelectionSetToObject {
597
594
  if (fragmentType == null) {
598
595
  throw new TypeError(`Unexpected error: Type ${selectionNode.onType} does not exist within schema.`);
599
596
  }
600
- // #region Recursively find all fields and nested fields of the SelectionSet
601
- // And by pushing the fields to `selectionNodes`
602
- // The for loop continues to build SelectionSet & nested SelectionSet exhaustively
603
597
  if (parentSchemaType.name === selectionNode.onType ||
604
598
  parentSchemaType
605
599
  .getInterfaces()
@@ -607,21 +601,14 @@ class SelectionSetToObject {
607
601
  ((0, graphql_1.isUnionType)(fragmentType) &&
608
602
  fragmentType.getTypes().find(objectType => objectType.name === parentSchemaType.name))) {
609
603
  // also process fields from fragment that apply for this parentType
610
- const { selectionNodesByTypeName, selectionNodesByTypeNameConditional } = this.flattenSelectionSet(selectionNode.selectionNodes, parentSchemaType);
604
+ const { selectionNodesByTypeName } = this.flattenSelectionSet(selectionNode.selectionNodes, parentSchemaType);
611
605
  const typeNodes = selectionNodesByTypeName.get(parentSchemaType.name) ?? [];
612
606
  selectionNodes.push(...typeNodes);
613
607
  for (const iinterface of parentSchemaType.getInterfaces()) {
614
608
  const typeNodes = selectionNodesByTypeName.get(iinterface.name) ?? [];
615
609
  selectionNodes.push(...typeNodes);
616
610
  }
617
- for (const conditionalNodes of selectionNodesByTypeNameConditional) {
618
- const _selectionNodes = (conditionalNodes.get(parentSchemaType.name) || []).filter((node) => 'fragmentDirectives' in node);
619
- for (const selectionNode of _selectionNodes) {
620
- selectionNodes.push(selectionNode);
621
- }
622
- }
623
611
  }
624
- // #endregion
625
612
  }
626
613
  const linkFields = [];
627
614
  const linkFieldsInterfaces = [];
@@ -650,30 +637,26 @@ class SelectionSetToObject {
650
637
  });
651
638
  }
652
639
  const typeInfoField = this.buildTypeNameField(parentSchemaType, this._config.nonOptionalTypename, requireTypename, this._config.skipTypeNameForRoot);
653
- // Only add the typename field if we're not merging fragment
654
- // types. If we are merging, we need to wait until we know all
655
- // the involved typenames.
656
- const transformedTypenameFields = typeInfoField &&
657
- (!this._config.mergeFragmentTypes || this._config.inlineFragmentTypes === 'mask')
658
- ? this._processor.transformTypenameField(typeInfoField.type, typeInfoField.name)
659
- : [];
660
- const transformedPrimitiveFields = this._processor.transformPrimitiveFields(parentSchemaType, Array.from(primitiveFields.values()).map(field => ({
661
- isConditional: (0, utils_js_1.hasConditionalDirectives)(field.directives) ||
662
- (0, utils_js_1.hasConditionalDirectives)(field.fragmentDirectives),
663
- fieldName: field.name.value,
664
- })), options.unsetTypes);
665
- const transformedAliasesPrimitiveFields = this._processor.transformAliasesPrimitiveFields(parentSchemaType, Array.from(primitiveAliasFields.values()).map(field => ({
666
- alias: field.alias.value,
667
- fieldName: field.name.value,
668
- isConditional: (0, utils_js_1.hasConditionalDirectives)(field.directives) ||
669
- (0, utils_js_1.hasConditionalDirectives)(field.fragmentDirectives),
670
- })), options.unsetTypes);
671
- const transformedLinkFields = this._processor.transformLinkFields(linkFields, options.unsetTypes);
672
640
  const transformed = [
673
- ...transformedTypenameFields,
674
- ...transformedPrimitiveFields,
675
- ...transformedAliasesPrimitiveFields,
676
- ...transformedLinkFields,
641
+ // Only add the typename field if we're not merging fragment
642
+ // types. If we are merging, we need to wait until we know all
643
+ // the involved typenames.
644
+ ...(typeInfoField &&
645
+ (!this._config.mergeFragmentTypes || this._config.inlineFragmentTypes === 'mask')
646
+ ? this._processor.transformTypenameField(typeInfoField.type, typeInfoField.name)
647
+ : []),
648
+ ...this._processor.transformPrimitiveFields(parentSchemaType, Array.from(primitiveFields.values()).map(field => ({
649
+ isConditional: (0, utils_js_1.hasConditionalDirectives)(field.directives) ||
650
+ (0, utils_js_1.hasConditionalDirectives)(field.fragmentDirectives),
651
+ fieldName: field.name.value,
652
+ })), options.unsetTypes),
653
+ ...this._processor.transformAliasesPrimitiveFields(parentSchemaType, Array.from(primitiveAliasFields.values()).map(field => ({
654
+ alias: field.alias.value,
655
+ fieldName: field.name.value,
656
+ isConditional: (0, utils_js_1.hasConditionalDirectives)(field.directives) ||
657
+ (0, utils_js_1.hasConditionalDirectives)(field.fragmentDirectives),
658
+ })), options.unsetTypes),
659
+ ...this._processor.transformLinkFields(linkFields, options.unsetTypes),
677
660
  ].filter(Boolean);
678
661
  const allStrings = transformed.filter(t => typeof t === 'string');
679
662
  const allObjectsMerged = transformed
@@ -770,7 +753,8 @@ class SelectionSetToObject {
770
753
  const dependentTypes = Object.keys(grouped)
771
754
  .map(typeName => {
772
755
  const relevant = grouped[typeName].filter(Boolean);
773
- return relevant.map(objDefinition => {
756
+ const hasTypesToMerge = relevant.length > 1;
757
+ return relevant.map((objDefinition, index) => {
774
758
  // In extractAllFieldsToTypesCompact mode, we still need to keep the final concrete type name for union/interface types
775
759
  // to distinguish between different implementations, but we skip it for simple object types
776
760
  const hasMultipleTypes = Object.keys(grouped).length > 1;
@@ -779,6 +763,9 @@ class SelectionSetToObject {
779
763
  if (this._config.extractAllFieldsToTypesCompact && !hasMultipleTypes) {
780
764
  name = fieldName;
781
765
  }
766
+ else if (this._config.extractAllFieldsToTypes && hasTypesToMerge) {
767
+ name = `${fieldName}_${typeName}_${index}`;
768
+ }
782
769
  else {
783
770
  name = `${fieldName}_${typeName}`;
784
771
  }
@@ -69,10 +69,7 @@ export class SelectionSetToObject {
69
69
  // fragment (using @defer).
70
70
  const fieldsWithFragmentDirectives = fields.map(field => ({
71
71
  ...field,
72
- // A field may already carry `fragmentDirectives` from an enclosing
73
- // conditional fragment spread; keep those in addition to the
74
- // directives on this inline fragment, instead of overwriting them.
75
- fragmentDirectives: [...(field.fragmentDirectives || []), ...(directives || [])],
72
+ fragmentDirectives: directives,
76
73
  }));
77
74
  if (isObjectType(typeOnSchema)) {
78
75
  this._appendToTypeMap(types, typeOnSchema.name, fieldsWithFragmentDirectives);
@@ -517,7 +514,7 @@ export class SelectionSetToObject {
517
514
  selectionNodes = [...selectionNodes];
518
515
  let inlineFragmentConditional = false;
519
516
  for (const selectionNode of selectionNodes) {
520
- // 1. Handle Field or Directives selection nodes
517
+ // 1. Handle Field or Directtives selection nodes
521
518
  if ('kind' in selectionNode) {
522
519
  if (selectionNode.kind === Kind.FIELD) {
523
520
  if (selectionNode.selectionSet) {
@@ -593,9 +590,6 @@ export class SelectionSetToObject {
593
590
  if (fragmentType == null) {
594
591
  throw new TypeError(`Unexpected error: Type ${selectionNode.onType} does not exist within schema.`);
595
592
  }
596
- // #region Recursively find all fields and nested fields of the SelectionSet
597
- // And by pushing the fields to `selectionNodes`
598
- // The for loop continues to build SelectionSet & nested SelectionSet exhaustively
599
593
  if (parentSchemaType.name === selectionNode.onType ||
600
594
  parentSchemaType
601
595
  .getInterfaces()
@@ -603,21 +597,14 @@ export class SelectionSetToObject {
603
597
  (isUnionType(fragmentType) &&
604
598
  fragmentType.getTypes().find(objectType => objectType.name === parentSchemaType.name))) {
605
599
  // also process fields from fragment that apply for this parentType
606
- const { selectionNodesByTypeName, selectionNodesByTypeNameConditional } = this.flattenSelectionSet(selectionNode.selectionNodes, parentSchemaType);
600
+ const { selectionNodesByTypeName } = this.flattenSelectionSet(selectionNode.selectionNodes, parentSchemaType);
607
601
  const typeNodes = selectionNodesByTypeName.get(parentSchemaType.name) ?? [];
608
602
  selectionNodes.push(...typeNodes);
609
603
  for (const iinterface of parentSchemaType.getInterfaces()) {
610
604
  const typeNodes = selectionNodesByTypeName.get(iinterface.name) ?? [];
611
605
  selectionNodes.push(...typeNodes);
612
606
  }
613
- for (const conditionalNodes of selectionNodesByTypeNameConditional) {
614
- const _selectionNodes = (conditionalNodes.get(parentSchemaType.name) || []).filter((node) => 'fragmentDirectives' in node);
615
- for (const selectionNode of _selectionNodes) {
616
- selectionNodes.push(selectionNode);
617
- }
618
- }
619
607
  }
620
- // #endregion
621
608
  }
622
609
  const linkFields = [];
623
610
  const linkFieldsInterfaces = [];
@@ -646,30 +633,26 @@ export class SelectionSetToObject {
646
633
  });
647
634
  }
648
635
  const typeInfoField = this.buildTypeNameField(parentSchemaType, this._config.nonOptionalTypename, requireTypename, this._config.skipTypeNameForRoot);
649
- // Only add the typename field if we're not merging fragment
650
- // types. If we are merging, we need to wait until we know all
651
- // the involved typenames.
652
- const transformedTypenameFields = typeInfoField &&
653
- (!this._config.mergeFragmentTypes || this._config.inlineFragmentTypes === 'mask')
654
- ? this._processor.transformTypenameField(typeInfoField.type, typeInfoField.name)
655
- : [];
656
- const transformedPrimitiveFields = this._processor.transformPrimitiveFields(parentSchemaType, Array.from(primitiveFields.values()).map(field => ({
657
- isConditional: hasConditionalDirectives(field.directives) ||
658
- hasConditionalDirectives(field.fragmentDirectives),
659
- fieldName: field.name.value,
660
- })), options.unsetTypes);
661
- const transformedAliasesPrimitiveFields = this._processor.transformAliasesPrimitiveFields(parentSchemaType, Array.from(primitiveAliasFields.values()).map(field => ({
662
- alias: field.alias.value,
663
- fieldName: field.name.value,
664
- isConditional: hasConditionalDirectives(field.directives) ||
665
- hasConditionalDirectives(field.fragmentDirectives),
666
- })), options.unsetTypes);
667
- const transformedLinkFields = this._processor.transformLinkFields(linkFields, options.unsetTypes);
668
636
  const transformed = [
669
- ...transformedTypenameFields,
670
- ...transformedPrimitiveFields,
671
- ...transformedAliasesPrimitiveFields,
672
- ...transformedLinkFields,
637
+ // Only add the typename field if we're not merging fragment
638
+ // types. If we are merging, we need to wait until we know all
639
+ // the involved typenames.
640
+ ...(typeInfoField &&
641
+ (!this._config.mergeFragmentTypes || this._config.inlineFragmentTypes === 'mask')
642
+ ? this._processor.transformTypenameField(typeInfoField.type, typeInfoField.name)
643
+ : []),
644
+ ...this._processor.transformPrimitiveFields(parentSchemaType, Array.from(primitiveFields.values()).map(field => ({
645
+ isConditional: hasConditionalDirectives(field.directives) ||
646
+ hasConditionalDirectives(field.fragmentDirectives),
647
+ fieldName: field.name.value,
648
+ })), options.unsetTypes),
649
+ ...this._processor.transformAliasesPrimitiveFields(parentSchemaType, Array.from(primitiveAliasFields.values()).map(field => ({
650
+ alias: field.alias.value,
651
+ fieldName: field.name.value,
652
+ isConditional: hasConditionalDirectives(field.directives) ||
653
+ hasConditionalDirectives(field.fragmentDirectives),
654
+ })), options.unsetTypes),
655
+ ...this._processor.transformLinkFields(linkFields, options.unsetTypes),
673
656
  ].filter(Boolean);
674
657
  const allStrings = transformed.filter(t => typeof t === 'string');
675
658
  const allObjectsMerged = transformed
@@ -766,7 +749,8 @@ export class SelectionSetToObject {
766
749
  const dependentTypes = Object.keys(grouped)
767
750
  .map(typeName => {
768
751
  const relevant = grouped[typeName].filter(Boolean);
769
- return relevant.map(objDefinition => {
752
+ const hasTypesToMerge = relevant.length > 1;
753
+ return relevant.map((objDefinition, index) => {
770
754
  // In extractAllFieldsToTypesCompact mode, we still need to keep the final concrete type name for union/interface types
771
755
  // to distinguish between different implementations, but we skip it for simple object types
772
756
  const hasMultipleTypes = Object.keys(grouped).length > 1;
@@ -775,6 +759,9 @@ export class SelectionSetToObject {
775
759
  if (this._config.extractAllFieldsToTypesCompact && !hasMultipleTypes) {
776
760
  name = fieldName;
777
761
  }
762
+ else if (this._config.extractAllFieldsToTypes && hasTypesToMerge) {
763
+ name = `${fieldName}_${typeName}_${index}`;
764
+ }
778
765
  else {
779
766
  name = `${fieldName}_${typeName}`;
780
767
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphql-codegen/visitor-plugin-common",
3
- "version": "7.2.1-alpha-20260719125849-4e20a28d5fee4dafc8a6cf0e22a03eedfd6ab3ff",
3
+ "version": "7.2.1",
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 || ^17.0.0"
6
6
  },
@@ -14,7 +14,7 @@ type FragmentSpreadUsage = {
14
14
  /**
15
15
  * @description EnrichedFieldNode are field nodes enriched with Codegen metadata for subsequent processing
16
16
  */
17
- export type EnrichedFieldNode = FieldNode & {
17
+ type EnrichedFieldNode = FieldNode & {
18
18
  /**
19
19
  * A field node may implicitly inherit fragment directives from parents
20
20
  * For example, if the field's parent is marked with `@skip`, the field is implicitly marked with `@skip` as well
@@ -14,7 +14,7 @@ type FragmentSpreadUsage = {
14
14
  /**
15
15
  * @description EnrichedFieldNode are field nodes enriched with Codegen metadata for subsequent processing
16
16
  */
17
- export type EnrichedFieldNode = FieldNode & {
17
+ type EnrichedFieldNode = FieldNode & {
18
18
  /**
19
19
  * A field node may implicitly inherit fragment directives from parents
20
20
  * For example, if the field's parent is marked with `@skip`, the field is implicitly marked with `@skip` as well
@@ -1,7 +1,6 @@
1
1
  import { DirectiveNode, EnumValueDefinitionNode, FieldDefinitionNode, FieldNode, FragmentSpreadNode, GraphQLInputObjectType, GraphQLNamedType, GraphQLObjectType, GraphQLOutputType, GraphQLSchema, InlineFragmentNode, InputValueDefinitionNode, NamedTypeNode, NameNode, SelectionNode, SelectionSetNode, StringValueNode, TypeNode } from 'graphql';
2
- import type { RawConfig } from './base-visitor.cjs';
3
- import type { EnrichedFieldNode } from './selection-set-to-object.cjs';
4
- import type { LoadedFragment, NormalizedScalarsMap, ParsedScalarsMap, ScalarsMap } from './types.cjs';
2
+ import { RawConfig } from './base-visitor.cjs';
3
+ import { LoadedFragment, NormalizedScalarsMap, ParsedScalarsMap, ScalarsMap } from './types.cjs';
5
4
  export declare const getConfigValue: <T = any>(value: T, defaultValue: T) => T;
6
5
  export declare function quoteIfNeeded(array: string[], joinWith?: string): string;
7
6
  export declare function block(array: any): string;
@@ -51,7 +50,7 @@ export declare const REQUIRE_FIELDS_TYPE = "export type RequireFields<T, K exten
51
50
  export declare function mergeSelectionSets(selectionSet1: SelectionSetNode, selectionSet2: SelectionSetNode): SelectionSetNode;
52
51
  export declare const getFieldNodeNameValue: (node: FieldNode) => string;
53
52
  export declare function separateSelectionSet(selections: ReadonlyArray<SelectionNode>): {
54
- fields: EnrichedFieldNode[];
53
+ fields: FieldNode[];
55
54
  spreads: FragmentSpreadNode[];
56
55
  inlines: InlineFragmentNode[];
57
56
  };
@@ -1,7 +1,6 @@
1
1
  import { DirectiveNode, EnumValueDefinitionNode, FieldDefinitionNode, FieldNode, FragmentSpreadNode, GraphQLInputObjectType, GraphQLNamedType, GraphQLObjectType, GraphQLOutputType, GraphQLSchema, InlineFragmentNode, InputValueDefinitionNode, NamedTypeNode, NameNode, SelectionNode, SelectionSetNode, StringValueNode, TypeNode } from 'graphql';
2
- import type { RawConfig } from './base-visitor.js';
3
- import type { EnrichedFieldNode } from './selection-set-to-object.js';
4
- import type { LoadedFragment, NormalizedScalarsMap, ParsedScalarsMap, ScalarsMap } from './types.js';
2
+ import { RawConfig } from './base-visitor.js';
3
+ import { LoadedFragment, NormalizedScalarsMap, ParsedScalarsMap, ScalarsMap } from './types.js';
5
4
  export declare const getConfigValue: <T = any>(value: T, defaultValue: T) => T;
6
5
  export declare function quoteIfNeeded(array: string[], joinWith?: string): string;
7
6
  export declare function block(array: any): string;
@@ -51,7 +50,7 @@ export declare const REQUIRE_FIELDS_TYPE = "export type RequireFields<T, K exten
51
50
  export declare function mergeSelectionSets(selectionSet1: SelectionSetNode, selectionSet2: SelectionSetNode): SelectionSetNode;
52
51
  export declare const getFieldNodeNameValue: (node: FieldNode) => string;
53
52
  export declare function separateSelectionSet(selections: ReadonlyArray<SelectionNode>): {
54
- fields: EnrichedFieldNode[];
53
+ fields: FieldNode[];
55
54
  spreads: FragmentSpreadNode[];
56
55
  inlines: InlineFragmentNode[];
57
56
  };