@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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
...
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
...
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
package/typings/utils.d.cts
CHANGED
|
@@ -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
|
|
3
|
-
import
|
|
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:
|
|
53
|
+
fields: FieldNode[];
|
|
55
54
|
spreads: FragmentSpreadNode[];
|
|
56
55
|
inlines: InlineFragmentNode[];
|
|
57
56
|
};
|
package/typings/utils.d.ts
CHANGED
|
@@ -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
|
|
3
|
-
import
|
|
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:
|
|
53
|
+
fields: FieldNode[];
|
|
55
54
|
spreads: FragmentSpreadNode[];
|
|
56
55
|
inlines: InlineFragmentNode[];
|
|
57
56
|
};
|