@graphql-codegen/visitor-plugin-common 5.7.1 → 5.8.0-alpha-20250316110831-3f757aba5365f95cb2ea64e6f2e73cd4ddd534a2

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.
@@ -47,6 +47,9 @@ class BaseResolversVisitor extends base_visitor_js_1.BaseVisitor {
47
47
  },
48
48
  resolversNonOptionalTypename: normalizeResolversNonOptionalTypename((0, utils_js_1.getConfigValue)(rawConfig.resolversNonOptionalTypename, false)),
49
49
  avoidCheckingAbstractTypesRecursively: (0, utils_js_1.getConfigValue)(rawConfig.avoidCheckingAbstractTypesRecursively, false),
50
+ customDirectives: {
51
+ semanticNonNull: rawConfig.customDirectives?.semanticNonNull ?? false,
52
+ },
50
53
  ...additionalConfig,
51
54
  });
52
55
  this._schema = _schema;
@@ -610,17 +613,11 @@ class BaseResolversVisitor extends base_visitor_js_1.BaseVisitor {
610
613
  const declarationKind = 'type';
611
614
  return (parentName, avoidResolverOptionals) => {
612
615
  const original = parent[key];
613
- const baseType = (0, utils_js_1.getBaseTypeNode)(original.type);
614
- const realType = baseType.name.value;
615
616
  const parentType = this.schema.getType(parentName);
616
617
  if (this._federation.skipField({ fieldNode: original, parentType })) {
617
618
  return null;
618
619
  }
619
620
  const contextType = this.getContextType(parentName, node);
620
- const typeToUse = this.getTypeToUse(realType);
621
- const mappedType = this._variablesTransformer.wrapAstTypeWithModifiers(typeToUse, original.type);
622
- const subscriptionType = this._schema.getSubscriptionType();
623
- const isSubscriptionType = subscriptionType && subscriptionType.name === parentName;
624
621
  let argsType = hasArguments
625
622
  ? this.convertName(parentName +
626
623
  (this.config.addUnderscoreToArgsType ? '_' : '') +
@@ -647,12 +644,35 @@ class BaseResolversVisitor extends base_visitor_js_1.BaseVisitor {
647
644
  parentType,
648
645
  parentTypeSignature: this.getParentTypeForSignature(node),
649
646
  });
650
- const mappedTypeKey = isSubscriptionType ? `${mappedType}, "${node.name}"` : mappedType;
651
- const directiveMappings = node.directives
652
- ?.map(directive => this._directiveResolverMappings[directive.name])
653
- .filter(Boolean)
654
- .reverse() ?? [];
655
- const resolverType = isSubscriptionType ? 'SubscriptionResolver' : directiveMappings[0] ?? 'Resolver';
647
+ const { mappedTypeKey, resolverType } = (() => {
648
+ const baseType = (0, utils_js_1.getBaseTypeNode)(original.type);
649
+ const realType = baseType.name.value;
650
+ const typeToUse = this.getTypeToUse(realType);
651
+ /**
652
+ * Turns GraphQL type to TypeScript types (`mappedType`) e.g.
653
+ * - String! -> ResolversTypes['String']>
654
+ * - String -> Maybe<ResolversTypes['String']>
655
+ * - [String] -> Maybe<Array<Maybe<ResolversTypes['String']>>>
656
+ * - [String!]! -> Array<ResolversTypes['String']>
657
+ */
658
+ const mappedType = this._variablesTransformer.wrapAstTypeWithModifiers(typeToUse, original.type);
659
+ const subscriptionType = this._schema.getSubscriptionType();
660
+ const isSubscriptionType = subscriptionType && subscriptionType.name === parentName;
661
+ if (isSubscriptionType) {
662
+ return {
663
+ mappedTypeKey: `${mappedType}, "${node.name}"`,
664
+ resolverType: 'SubscriptionResolver',
665
+ };
666
+ }
667
+ const directiveMappings = node.directives
668
+ ?.map(directive => this._directiveResolverMappings[directive.name])
669
+ .filter(Boolean)
670
+ .reverse() ?? [];
671
+ return {
672
+ mappedTypeKey: this.modifyFieldDefinitionNodeTransformedType({ node: original, originalType: mappedType }),
673
+ resolverType: directiveMappings[0] ?? 'Resolver',
674
+ };
675
+ })();
656
676
  const signature = {
657
677
  name: node.name,
658
678
  modifier: avoidResolverOptionals ? '' : '?',
@@ -699,6 +719,26 @@ class BaseResolversVisitor extends base_visitor_js_1.BaseVisitor {
699
719
  applyOptionalFields(argsType, _fields) {
700
720
  return `Partial<${argsType}>`;
701
721
  }
722
+ /**
723
+ * Function to apply extra transformation to a FieldDefinitionNode's TypeScript type based on config options
724
+ * e.g. takes `Maybe<ResolversTypes['String']>`, and returns the type without the `Maybe<>` wrapper.
725
+ */
726
+ modifyFieldDefinitionNodeTransformedType({ node, originalType, }) {
727
+ let result = originalType;
728
+ if (this.config.customDirectives.semanticNonNull) {
729
+ const fieldHasSemanticNonNull = node.directives.some(d => d.name.value === 'semanticNonNull');
730
+ if (fieldHasSemanticNonNull) {
731
+ result = this.clearOptional(result);
732
+ }
733
+ }
734
+ return result;
735
+ }
736
+ clearOptional(str) {
737
+ if (str.startsWith('Maybe')) {
738
+ return str.replace(/Maybe<(.*?)>$/, '$1');
739
+ }
740
+ return str;
741
+ }
702
742
  ObjectTypeDefinition(node) {
703
743
  const declarationKind = 'type';
704
744
  const name = this.convertName(node, {
@@ -43,6 +43,9 @@ export class BaseResolversVisitor extends BaseVisitor {
43
43
  },
44
44
  resolversNonOptionalTypename: normalizeResolversNonOptionalTypename(getConfigValue(rawConfig.resolversNonOptionalTypename, false)),
45
45
  avoidCheckingAbstractTypesRecursively: getConfigValue(rawConfig.avoidCheckingAbstractTypesRecursively, false),
46
+ customDirectives: {
47
+ semanticNonNull: rawConfig.customDirectives?.semanticNonNull ?? false,
48
+ },
46
49
  ...additionalConfig,
47
50
  });
48
51
  this._schema = _schema;
@@ -606,17 +609,11 @@ export class BaseResolversVisitor extends BaseVisitor {
606
609
  const declarationKind = 'type';
607
610
  return (parentName, avoidResolverOptionals) => {
608
611
  const original = parent[key];
609
- const baseType = getBaseTypeNode(original.type);
610
- const realType = baseType.name.value;
611
612
  const parentType = this.schema.getType(parentName);
612
613
  if (this._federation.skipField({ fieldNode: original, parentType })) {
613
614
  return null;
614
615
  }
615
616
  const contextType = this.getContextType(parentName, node);
616
- const typeToUse = this.getTypeToUse(realType);
617
- const mappedType = this._variablesTransformer.wrapAstTypeWithModifiers(typeToUse, original.type);
618
- const subscriptionType = this._schema.getSubscriptionType();
619
- const isSubscriptionType = subscriptionType && subscriptionType.name === parentName;
620
617
  let argsType = hasArguments
621
618
  ? this.convertName(parentName +
622
619
  (this.config.addUnderscoreToArgsType ? '_' : '') +
@@ -643,12 +640,35 @@ export class BaseResolversVisitor extends BaseVisitor {
643
640
  parentType,
644
641
  parentTypeSignature: this.getParentTypeForSignature(node),
645
642
  });
646
- const mappedTypeKey = isSubscriptionType ? `${mappedType}, "${node.name}"` : mappedType;
647
- const directiveMappings = node.directives
648
- ?.map(directive => this._directiveResolverMappings[directive.name])
649
- .filter(Boolean)
650
- .reverse() ?? [];
651
- const resolverType = isSubscriptionType ? 'SubscriptionResolver' : directiveMappings[0] ?? 'Resolver';
643
+ const { mappedTypeKey, resolverType } = (() => {
644
+ const baseType = getBaseTypeNode(original.type);
645
+ const realType = baseType.name.value;
646
+ const typeToUse = this.getTypeToUse(realType);
647
+ /**
648
+ * Turns GraphQL type to TypeScript types (`mappedType`) e.g.
649
+ * - String! -> ResolversTypes['String']>
650
+ * - String -> Maybe<ResolversTypes['String']>
651
+ * - [String] -> Maybe<Array<Maybe<ResolversTypes['String']>>>
652
+ * - [String!]! -> Array<ResolversTypes['String']>
653
+ */
654
+ const mappedType = this._variablesTransformer.wrapAstTypeWithModifiers(typeToUse, original.type);
655
+ const subscriptionType = this._schema.getSubscriptionType();
656
+ const isSubscriptionType = subscriptionType && subscriptionType.name === parentName;
657
+ if (isSubscriptionType) {
658
+ return {
659
+ mappedTypeKey: `${mappedType}, "${node.name}"`,
660
+ resolverType: 'SubscriptionResolver',
661
+ };
662
+ }
663
+ const directiveMappings = node.directives
664
+ ?.map(directive => this._directiveResolverMappings[directive.name])
665
+ .filter(Boolean)
666
+ .reverse() ?? [];
667
+ return {
668
+ mappedTypeKey: this.modifyFieldDefinitionNodeTransformedType({ node: original, originalType: mappedType }),
669
+ resolverType: directiveMappings[0] ?? 'Resolver',
670
+ };
671
+ })();
652
672
  const signature = {
653
673
  name: node.name,
654
674
  modifier: avoidResolverOptionals ? '' : '?',
@@ -695,6 +715,26 @@ export class BaseResolversVisitor extends BaseVisitor {
695
715
  applyOptionalFields(argsType, _fields) {
696
716
  return `Partial<${argsType}>`;
697
717
  }
718
+ /**
719
+ * Function to apply extra transformation to a FieldDefinitionNode's TypeScript type based on config options
720
+ * e.g. takes `Maybe<ResolversTypes['String']>`, and returns the type without the `Maybe<>` wrapper.
721
+ */
722
+ modifyFieldDefinitionNodeTransformedType({ node, originalType, }) {
723
+ let result = originalType;
724
+ if (this.config.customDirectives.semanticNonNull) {
725
+ const fieldHasSemanticNonNull = node.directives.some(d => d.name.value === 'semanticNonNull');
726
+ if (fieldHasSemanticNonNull) {
727
+ result = this.clearOptional(result);
728
+ }
729
+ }
730
+ return result;
731
+ }
732
+ clearOptional(str) {
733
+ if (str.startsWith('Maybe')) {
734
+ return str.replace(/Maybe<(.*?)>$/, '$1');
735
+ }
736
+ return str;
737
+ }
698
738
  ObjectTypeDefinition(node) {
699
739
  const declarationKind = 'type';
700
740
  const name = this.convertName(node, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphql-codegen/visitor-plugin-common",
3
- "version": "5.7.1",
3
+ "version": "5.8.0-alpha-20250316110831-3f757aba5365f95cb2ea64e6f2e73cd4ddd534a2",
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
  },
@@ -32,6 +32,9 @@ export interface ParsedResolversConfig extends ParsedConfig {
32
32
  directiveResolverMappings: Record<string, string>;
33
33
  resolversNonOptionalTypename: ResolversNonOptionalTypenameConfig;
34
34
  avoidCheckingAbstractTypesRecursively: boolean;
35
+ customDirectives: {
36
+ semanticNonNull: boolean;
37
+ };
35
38
  }
36
39
  type FieldDefinitionPrintFn = (parentName: string, avoidResolverOptionals: boolean) => string | null;
37
40
  export interface RootResolver {
@@ -505,6 +508,31 @@ export interface RawResolversConfig extends RawConfig {
505
508
  * ```
506
509
  */
507
510
  enumSuffix?: boolean;
511
+ /**
512
+ * @description Configures behavior for custom directives from various GraphQL libraries.
513
+ * @exampleMarkdown
514
+ * ```ts filename="codegen.ts"
515
+ * import type { CodegenConfig } from '@graphql-codegen/cli';
516
+ *
517
+ * const config: CodegenConfig = {
518
+ * // ...
519
+ * generates: {
520
+ * 'path/to/file.ts': {
521
+ * plugins: ['typescript-resolvers'],
522
+ * config: {
523
+ * customDirectives: {
524
+ * semanticNonNull: true
525
+ * }
526
+ * },
527
+ * },
528
+ * },
529
+ * };
530
+ * export default config;
531
+ * ```
532
+ */
533
+ customDirectives?: {
534
+ semanticNonNull?: boolean;
535
+ };
508
536
  /**
509
537
  * @default false
510
538
  * @description Sets the `__resolveType` field as optional field.
@@ -721,6 +749,15 @@ export declare class BaseResolversVisitor<TRawConfig extends RawResolversConfig
721
749
  private getContextType;
722
750
  protected applyRequireFields(argsType: string, fields: InputValueDefinitionNode[]): string;
723
751
  protected applyOptionalFields(argsType: string, _fields: readonly InputValueDefinitionNode[]): string;
752
+ /**
753
+ * Function to apply extra transformation to a FieldDefinitionNode's TypeScript type based on config options
754
+ * e.g. takes `Maybe<ResolversTypes['String']>`, and returns the type without the `Maybe<>` wrapper.
755
+ */
756
+ protected modifyFieldDefinitionNodeTransformedType({ node, originalType, }: {
757
+ node: FieldDefinitionNode;
758
+ originalType: string;
759
+ }): string;
760
+ protected clearOptional(str: string): string;
724
761
  ObjectTypeDefinition(node: ObjectTypeDefinitionNode): string;
725
762
  UnionTypeDefinition(node: UnionTypeDefinitionNode, key: string | number, parent: any): string;
726
763
  ScalarTypeDefinition(node: ScalarTypeDefinitionNode): string;
@@ -32,6 +32,9 @@ export interface ParsedResolversConfig extends ParsedConfig {
32
32
  directiveResolverMappings: Record<string, string>;
33
33
  resolversNonOptionalTypename: ResolversNonOptionalTypenameConfig;
34
34
  avoidCheckingAbstractTypesRecursively: boolean;
35
+ customDirectives: {
36
+ semanticNonNull: boolean;
37
+ };
35
38
  }
36
39
  type FieldDefinitionPrintFn = (parentName: string, avoidResolverOptionals: boolean) => string | null;
37
40
  export interface RootResolver {
@@ -505,6 +508,31 @@ export interface RawResolversConfig extends RawConfig {
505
508
  * ```
506
509
  */
507
510
  enumSuffix?: boolean;
511
+ /**
512
+ * @description Configures behavior for custom directives from various GraphQL libraries.
513
+ * @exampleMarkdown
514
+ * ```ts filename="codegen.ts"
515
+ * import type { CodegenConfig } from '@graphql-codegen/cli';
516
+ *
517
+ * const config: CodegenConfig = {
518
+ * // ...
519
+ * generates: {
520
+ * 'path/to/file.ts': {
521
+ * plugins: ['typescript-resolvers'],
522
+ * config: {
523
+ * customDirectives: {
524
+ * semanticNonNull: true
525
+ * }
526
+ * },
527
+ * },
528
+ * },
529
+ * };
530
+ * export default config;
531
+ * ```
532
+ */
533
+ customDirectives?: {
534
+ semanticNonNull?: boolean;
535
+ };
508
536
  /**
509
537
  * @default false
510
538
  * @description Sets the `__resolveType` field as optional field.
@@ -721,6 +749,15 @@ export declare class BaseResolversVisitor<TRawConfig extends RawResolversConfig
721
749
  private getContextType;
722
750
  protected applyRequireFields(argsType: string, fields: InputValueDefinitionNode[]): string;
723
751
  protected applyOptionalFields(argsType: string, _fields: readonly InputValueDefinitionNode[]): string;
752
+ /**
753
+ * Function to apply extra transformation to a FieldDefinitionNode's TypeScript type based on config options
754
+ * e.g. takes `Maybe<ResolversTypes['String']>`, and returns the type without the `Maybe<>` wrapper.
755
+ */
756
+ protected modifyFieldDefinitionNodeTransformedType({ node, originalType, }: {
757
+ node: FieldDefinitionNode;
758
+ originalType: string;
759
+ }): string;
760
+ protected clearOptional(str: string): string;
724
761
  ObjectTypeDefinition(node: ObjectTypeDefinitionNode): string;
725
762
  UnionTypeDefinition(node: UnionTypeDefinitionNode, key: string | number, parent: any): string;
726
763
  ScalarTypeDefinition(node: ScalarTypeDefinitionNode): string;