@graphql-codegen/visitor-plugin-common 7.2.0 → 7.2.1-alpha-20260719125849-4e20a28d5fee4dafc8a6cf0e22a03eedfd6ab3ff
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,7 +73,10 @@ class SelectionSetToObject {
|
|
|
73
73
|
// fragment (using @defer).
|
|
74
74
|
const fieldsWithFragmentDirectives = fields.map(field => ({
|
|
75
75
|
...field,
|
|
76
|
-
fragmentDirectives
|
|
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 || [])],
|
|
77
80
|
}));
|
|
78
81
|
if ((0, graphql_1.isObjectType)(typeOnSchema)) {
|
|
79
82
|
this._appendToTypeMap(types, typeOnSchema.name, fieldsWithFragmentDirectives);
|
|
@@ -518,7 +521,7 @@ class SelectionSetToObject {
|
|
|
518
521
|
selectionNodes = [...selectionNodes];
|
|
519
522
|
let inlineFragmentConditional = false;
|
|
520
523
|
for (const selectionNode of selectionNodes) {
|
|
521
|
-
// 1. Handle Field or
|
|
524
|
+
// 1. Handle Field or Directives selection nodes
|
|
522
525
|
if ('kind' in selectionNode) {
|
|
523
526
|
if (selectionNode.kind === graphql_1.Kind.FIELD) {
|
|
524
527
|
if (selectionNode.selectionSet) {
|
|
@@ -594,6 +597,9 @@ class SelectionSetToObject {
|
|
|
594
597
|
if (fragmentType == null) {
|
|
595
598
|
throw new TypeError(`Unexpected error: Type ${selectionNode.onType} does not exist within schema.`);
|
|
596
599
|
}
|
|
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
|
|
597
603
|
if (parentSchemaType.name === selectionNode.onType ||
|
|
598
604
|
parentSchemaType
|
|
599
605
|
.getInterfaces()
|
|
@@ -601,14 +607,21 @@ class SelectionSetToObject {
|
|
|
601
607
|
((0, graphql_1.isUnionType)(fragmentType) &&
|
|
602
608
|
fragmentType.getTypes().find(objectType => objectType.name === parentSchemaType.name))) {
|
|
603
609
|
// also process fields from fragment that apply for this parentType
|
|
604
|
-
const { selectionNodesByTypeName } = this.flattenSelectionSet(selectionNode.selectionNodes, parentSchemaType);
|
|
610
|
+
const { selectionNodesByTypeName, selectionNodesByTypeNameConditional } = this.flattenSelectionSet(selectionNode.selectionNodes, parentSchemaType);
|
|
605
611
|
const typeNodes = selectionNodesByTypeName.get(parentSchemaType.name) ?? [];
|
|
606
612
|
selectionNodes.push(...typeNodes);
|
|
607
613
|
for (const iinterface of parentSchemaType.getInterfaces()) {
|
|
608
614
|
const typeNodes = selectionNodesByTypeName.get(iinterface.name) ?? [];
|
|
609
615
|
selectionNodes.push(...typeNodes);
|
|
610
616
|
}
|
|
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
|
+
}
|
|
611
623
|
}
|
|
624
|
+
// #endregion
|
|
612
625
|
}
|
|
613
626
|
const linkFields = [];
|
|
614
627
|
const linkFieldsInterfaces = [];
|
|
@@ -637,26 +650,30 @@ class SelectionSetToObject {
|
|
|
637
650
|
});
|
|
638
651
|
}
|
|
639
652
|
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);
|
|
640
672
|
const transformed = [
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
...
|
|
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),
|
|
673
|
+
...transformedTypenameFields,
|
|
674
|
+
...transformedPrimitiveFields,
|
|
675
|
+
...transformedAliasesPrimitiveFields,
|
|
676
|
+
...transformedLinkFields,
|
|
660
677
|
].filter(Boolean);
|
|
661
678
|
const allStrings = transformed.filter(t => typeof t === 'string');
|
|
662
679
|
const allObjectsMerged = transformed
|
|
@@ -69,7 +69,10 @@ export class SelectionSetToObject {
|
|
|
69
69
|
// fragment (using @defer).
|
|
70
70
|
const fieldsWithFragmentDirectives = fields.map(field => ({
|
|
71
71
|
...field,
|
|
72
|
-
fragmentDirectives
|
|
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 || [])],
|
|
73
76
|
}));
|
|
74
77
|
if (isObjectType(typeOnSchema)) {
|
|
75
78
|
this._appendToTypeMap(types, typeOnSchema.name, fieldsWithFragmentDirectives);
|
|
@@ -514,7 +517,7 @@ export class SelectionSetToObject {
|
|
|
514
517
|
selectionNodes = [...selectionNodes];
|
|
515
518
|
let inlineFragmentConditional = false;
|
|
516
519
|
for (const selectionNode of selectionNodes) {
|
|
517
|
-
// 1. Handle Field or
|
|
520
|
+
// 1. Handle Field or Directives selection nodes
|
|
518
521
|
if ('kind' in selectionNode) {
|
|
519
522
|
if (selectionNode.kind === Kind.FIELD) {
|
|
520
523
|
if (selectionNode.selectionSet) {
|
|
@@ -590,6 +593,9 @@ export class SelectionSetToObject {
|
|
|
590
593
|
if (fragmentType == null) {
|
|
591
594
|
throw new TypeError(`Unexpected error: Type ${selectionNode.onType} does not exist within schema.`);
|
|
592
595
|
}
|
|
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
|
|
593
599
|
if (parentSchemaType.name === selectionNode.onType ||
|
|
594
600
|
parentSchemaType
|
|
595
601
|
.getInterfaces()
|
|
@@ -597,14 +603,21 @@ export class SelectionSetToObject {
|
|
|
597
603
|
(isUnionType(fragmentType) &&
|
|
598
604
|
fragmentType.getTypes().find(objectType => objectType.name === parentSchemaType.name))) {
|
|
599
605
|
// also process fields from fragment that apply for this parentType
|
|
600
|
-
const { selectionNodesByTypeName } = this.flattenSelectionSet(selectionNode.selectionNodes, parentSchemaType);
|
|
606
|
+
const { selectionNodesByTypeName, selectionNodesByTypeNameConditional } = this.flattenSelectionSet(selectionNode.selectionNodes, parentSchemaType);
|
|
601
607
|
const typeNodes = selectionNodesByTypeName.get(parentSchemaType.name) ?? [];
|
|
602
608
|
selectionNodes.push(...typeNodes);
|
|
603
609
|
for (const iinterface of parentSchemaType.getInterfaces()) {
|
|
604
610
|
const typeNodes = selectionNodesByTypeName.get(iinterface.name) ?? [];
|
|
605
611
|
selectionNodes.push(...typeNodes);
|
|
606
612
|
}
|
|
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
|
+
}
|
|
607
619
|
}
|
|
620
|
+
// #endregion
|
|
608
621
|
}
|
|
609
622
|
const linkFields = [];
|
|
610
623
|
const linkFieldsInterfaces = [];
|
|
@@ -633,26 +646,30 @@ export class SelectionSetToObject {
|
|
|
633
646
|
});
|
|
634
647
|
}
|
|
635
648
|
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);
|
|
636
668
|
const transformed = [
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
...
|
|
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),
|
|
669
|
+
...transformedTypenameFields,
|
|
670
|
+
...transformedPrimitiveFields,
|
|
671
|
+
...transformedAliasesPrimitiveFields,
|
|
672
|
+
...transformedLinkFields,
|
|
656
673
|
].filter(Boolean);
|
|
657
674
|
const allStrings = transformed.filter(t => typeof t === 'string');
|
|
658
675
|
const allObjectsMerged = transformed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphql-codegen/visitor-plugin-common",
|
|
3
|
-
"version": "7.2.
|
|
3
|
+
"version": "7.2.1-alpha-20260719125849-4e20a28d5fee4dafc8a6cf0e22a03eedfd6ab3ff",
|
|
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
|
-
type EnrichedFieldNode = FieldNode & {
|
|
17
|
+
export 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
|
-
type EnrichedFieldNode = FieldNode & {
|
|
17
|
+
export 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,6 +1,7 @@
|
|
|
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 { RawConfig } from './base-visitor.cjs';
|
|
3
|
-
import {
|
|
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';
|
|
4
5
|
export declare const getConfigValue: <T = any>(value: T, defaultValue: T) => T;
|
|
5
6
|
export declare function quoteIfNeeded(array: string[], joinWith?: string): string;
|
|
6
7
|
export declare function block(array: any): string;
|
|
@@ -50,7 +51,7 @@ export declare const REQUIRE_FIELDS_TYPE = "export type RequireFields<T, K exten
|
|
|
50
51
|
export declare function mergeSelectionSets(selectionSet1: SelectionSetNode, selectionSet2: SelectionSetNode): SelectionSetNode;
|
|
51
52
|
export declare const getFieldNodeNameValue: (node: FieldNode) => string;
|
|
52
53
|
export declare function separateSelectionSet(selections: ReadonlyArray<SelectionNode>): {
|
|
53
|
-
fields:
|
|
54
|
+
fields: EnrichedFieldNode[];
|
|
54
55
|
spreads: FragmentSpreadNode[];
|
|
55
56
|
inlines: InlineFragmentNode[];
|
|
56
57
|
};
|
package/typings/utils.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
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 { RawConfig } from './base-visitor.js';
|
|
3
|
-
import {
|
|
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';
|
|
4
5
|
export declare const getConfigValue: <T = any>(value: T, defaultValue: T) => T;
|
|
5
6
|
export declare function quoteIfNeeded(array: string[], joinWith?: string): string;
|
|
6
7
|
export declare function block(array: any): string;
|
|
@@ -50,7 +51,7 @@ export declare const REQUIRE_FIELDS_TYPE = "export type RequireFields<T, K exten
|
|
|
50
51
|
export declare function mergeSelectionSets(selectionSet1: SelectionSetNode, selectionSet2: SelectionSetNode): SelectionSetNode;
|
|
51
52
|
export declare const getFieldNodeNameValue: (node: FieldNode) => string;
|
|
52
53
|
export declare function separateSelectionSet(selections: ReadonlyArray<SelectionNode>): {
|
|
53
|
-
fields:
|
|
54
|
+
fields: EnrichedFieldNode[];
|
|
54
55
|
spreads: FragmentSpreadNode[];
|
|
55
56
|
inlines: InlineFragmentNode[];
|
|
56
57
|
};
|