Coder Social home page Coder Social logo

graphql-code-generator-community's Introduction

CodeGen

GraphQL Code Generator: Community plugins

This repository is owned by the GraphQL Code Generator community and is home to the community plugins:

  • npm version - @graphql-codegen/typescript-react-apollo
  • npm version - @graphql-codegen/typescript-graphql-request
  • npm version - @graphql-codegen/typescript-apollo-angular
  • npm version - @graphql-codegen/typescript-apollo-client-helpers
  • npm version - @graphql-codegen/typescript-react-query
  • npm version - @graphql-codegen/typescript-urql
  • npm version - @graphql-codegen/named-operations-object
  • npm version - @graphql-codegen/urql-introspection
  • npm version - @graphql-codegen/flow-resolvers
  • npm version - @graphql-codegen/typescript-vue-apollo
  • npm version - @graphql-codegen/typescript-rtk-query
  • npm version - @graphql-codegen/flow-operations
  • npm version - @graphql-codegen/typescript-msw
  • npm version - @graphql-codegen/typescript-mongodb
  • npm version - @graphql-codegen/typescript-nhost
  • npm version - @graphql-codegen/typescript-type-graphql
  • npm version - @graphql-codegen/jsdoc
  • npm version - @graphql-codegen/typescript-vue-urql
  • npm version - @graphql-codegen/kotlin
  • npm version - @graphql-codegen/typescript-vue-apollo-smart-ops
  • npm version - @graphql-codegen/java
  • npm version - @graphql-codegen/c-sharp-operations
  • npm version - @graphql-codegen/hasura-allow-list
  • npm version - @graphql-codegen/typescript-stencil-apollo
  • npm version - @graphql-codegen/relay-operation-optimizer
  • npm version - @graphql-codegen/typescript-oclif
  • npm version - @graphql-codegen/java-resolvers
  • npm version - @graphql-codegen/java-apollo-android
  • npm version - @graphql-codegen/typescript-nest

Getting started with codegen

You can find the complete instructions in GraphQL Code Generator website.

Start by installing the basic dependencies of GraphQL Codegen;

yarn add graphql typescript
yarn add -D @graphql-codegen/cli

Contributing

If this is your first time contributing to this project, please do read our Contributor Workflow Guide before you get started off.

Feel free to open issues and pull requests. We're always welcome support from the community.

For a contribution guide specific to this project, please refer to: http://graphql-code-generator.com/docs/custom-codegen/contributing

Create a new community plugin

Get started with our guide: https://www.the-guild.dev/graphql/codegen/docs/custom-codegen

Code of Conduct

Help us keep GraphQL Codegenerator open and inclusive. Please read and follow our Code of Conduct as adopted from Contributor Covenant

License

GitHub license

MIT

graphql-code-generator-community's People

Contributors

ardatan avatar borremosch avatar carlopalinckx avatar charlypoly avatar cklam2 avatar cometkim avatar dab0mb avatar dependabot[bot] avatar dimamachina avatar dotansimha avatar fredyc avatar gilgardosh avatar github-actions[bot] avatar greenkeeper[bot] avatar jonaskello avatar kamilkisiela avatar leonardfactory avatar lucasavila00 avatar micimize avatar mvestergaard avatar n1ru4l avatar renovate-bot avatar renovate[bot] avatar saihaj avatar simenb avatar standy avatar theguild-bot avatar tvvignesh avatar tzachs avatar zephraph avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

graphql-code-generator-community's Issues

Cannot read/write nested fragments

Versions

Versions

Describe the bug

In our project, we create a new GraphQL file for each query, mutation, and fragment. Out of that, a types file is generated, including the GraphQL document.

We're making use of the Apollo write/read fragment feature, in order to store some state in the Apollo cache or simply overwrite some data. For this, we use the document of the fragment from the generated types file.

With the latest update, we get an error, that no fragment was found for a specific name. We looked a bit deeper into that and found out, for fragments that import another fragment, the fragment is not included in the respective document.

fragment Zip on Zip {
   zip
}
#import "./zip.fragment.gql"
fragment Address on Address {
   street
   zip {
     ...Zip
   } 
}
import { AddressFragmentDoc } from './address.fragment.gql-types.tsx';

client.writeFragment({
   fragment: AddressFragmentDoc,
   data: {
      // the data
   }
})

This causes the following error: Invariant Violation: No fragment named Zip.

Looking into the changes of our current upgrade PR, we can see that for all fragments that all fragment.definitions assignments to the document got removed, while they been added to the respective query and mutations.

Example:

export const AddressFragmentDoc = {
  kind: 'Document',
  defintions: [
    {
       // the current fragment document defintion
    }
-    ...ZipFragmentDoc.definitions
  ]
}

It seems, by removing the definitions of the imported fragment we lose the information about the fragment.

Questions

  • is this a bug?
  • is there any configuration around this issue?

typescript-vue-urql not using useClientHandle -> causing error with suspense

Describe the bug
In the @graphql-codegen/typescript-vue-urql plugin, the composition functions refer to the global Urql imported as such: import * as Urql from '@urql/vue';. Whilst this can be configured to point to a different instance, there isn't any support for useClientHandle.

Why is this important?
When using an async setup function, only one promise can be awaited. Therefore, if I generate two queries and call/await on them sequentially, the second will throw the error: Error: use* functions may only be called during the setup() or other lifecycle hooks..

The problem is explained by the urql team here.

To Reproduce

import { useFlightsFromOriginQuery, useFlightsToDestinationQuery } from '../generated/graphql'

export async function useRoutes() {
  const originFlights = await useFlightsFromOriginQuery()
  const destinationFlights = await useFlightsToDestinationQuery()

return { originFlights, destinationFlights }

The error Error: use* functions may only be called during the setup() or other lifecycle hooks. is thrown when I am calling from my setup function:

<script setup>
import { useRoutes } from '../composables/useRoutes'

const responses = await useRoutes()

</script>

However, this error does not throw if I change the useRoutes() query to only run one of the queries and not the other. As explained by the urql team, this doesn't necessarily mean two queries generated from this library, it means any two promises in the setup function.

This means we need to create the clientHandle in the original setup function and pass it into the use* generated query.

Perhaps the easiest way to fix this is to pass down the Urql as an optional parameter to the auto-generated composition function:
https://github.com/dotansimha/graphql-code-generator/blob/988b8b67294e15b7548a554226ee51fce5a4ef4f/packages/plugins/typescript/vue-urql/src/visitor.ts#L73-L74

Which means from my calling code, I can write:

import { useClientHandle } from '@urql/vue'
import { useFlightsFromOriginQuery, useFlightsToDestinationQuery } from '../generated/graphql'

export async function useRoutes() {
  const client = useClientHandle()
  const originFlights = await useFlightsFromOriginQuery({}, client)
  const destinationFlights = await useFlightsToDestinationQuery({}, client)

return { originFlights, destinationFlights }

I looked at this as an alternative:
https://github.com/dotansimha/graphql-code-generator/blob/988b8b67294e15b7548a554226ee51fce5a4ef4f/packages/plugins/typescript/vue-urql/src/visitor.ts#L38

But we can't call useClientHandle() until we are actually inside the setup function, meaning the actual composition functions need to change OR we just pass it in from outside.

Perhaps it would be neater if we merged it as an option to the default UseQueryArgs, but I'm open to different options.

Sandbox with types generated:
https://codesandbox.io/s/elated-ramanujan-vf6jq?file=/types.ts

"Import type" preset with "typescript-resolvers" doesn't work well

Describe the bug

I made types with prefix "T". but when I generated resolver types, It doesn't have "T" prefix.

codegen

overwrite: true
schema: "src/schema/**/*.type.gql"
documents: "src/schema/**/*.document.gql"
config:
  typesPrefix: T
  enumPrefix: false
  namingConvention:
    enumValues: keep
generates:
  src/generated/type.ts:
    plugins:
      - "typescript"
      - "typescript-operations"
  src/generated/resolver.ts:
    preset: "import-types"
    presetConfig:
      typesPath: "generated/type"
    plugins:
      - "typescript-resolvers"
    config:
      useIndexSignature: true

gql files

test.document.gql

type User {
  id: String!
  name: String!
}

type Query {
  getUser: User
}

test.type.gql

type User {
  id: String!
  name: String!
}

type Query {
  getUser: User
}

generated files

type.ts

export type Maybe<T> = T | null;
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
  ID: string;
  String: string;
  Boolean: boolean;
  Int: number;
  Float: number;
};

export type TUser = {
  __typename?: 'User';
  id: Scalars['String'];
  name: Scalars['String'];
};

export type TQuery = {
  __typename?: 'Query';
  getUser?: Maybe<TUser>;
};

export type TGetUserQueryVariables = Exact<{ [key: string]: never; }>;


export type TGetUserQuery = (
  { __typename?: 'Query' }
  & { getUser?: Maybe<(
    { __typename?: 'User' }
    & Pick<TUser, 'id' | 'name'>
  )> }
);

resolver.ts

import * as Types from 'generated/type';

import { GraphQLResolveInfo } from 'graphql';
export type WithIndex<TObject> = TObject & Record<string, any>;
export type ResolversObject<TObject> = WithIndex<TObject>;

export type ResolverTypeWrapper<T> = Promise<T> | T;


export type LegacyStitchingResolver<TResult, TParent, TContext, TArgs> = {
  fragment: string;
  resolve: ResolverFn<TResult, TParent, TContext, TArgs>;
};

export type NewStitchingResolver<TResult, TParent, TContext, TArgs> = {
  selectionSet: string;
  resolve: ResolverFn<TResult, TParent, TContext, TArgs>;
};
export type StitchingResolver<TResult, TParent, TContext, TArgs> = LegacyStitchingResolver<TResult, TParent, TContext, TArgs> | NewStitchingResolver<TResult, TParent, TContext, TArgs>;
export type Resolver<TResult, TParent = {}, TContext = {}, TArgs = {}> =
  | ResolverFn<TResult, TParent, TContext, TArgs>
  | StitchingResolver<TResult, TParent, TContext, TArgs>;

export type ResolverFn<TResult, TParent, TContext, TArgs> = (
  parent: TParent,
  args: TArgs,
  context: TContext,
  info: GraphQLResolveInfo
) => Promise<TResult> | TResult;

export type SubscriptionSubscribeFn<TResult, TParent, TContext, TArgs> = (
  parent: TParent,
  args: TArgs,
  context: TContext,
  info: GraphQLResolveInfo
) => AsyncIterator<TResult> | Promise<AsyncIterator<TResult>>;

export type SubscriptionResolveFn<TResult, TParent, TContext, TArgs> = (
  parent: TParent,
  args: TArgs,
  context: TContext,
  info: GraphQLResolveInfo
) => TResult | Promise<TResult>;

export interface SubscriptionSubscriberObject<TResult, TKey extends string, TParent, TContext, TArgs> {
  subscribe: SubscriptionSubscribeFn<{ [key in TKey]: TResult }, TParent, TContext, TArgs>;
  resolve?: SubscriptionResolveFn<TResult, { [key in TKey]: TResult }, TContext, TArgs>;
}

export interface SubscriptionResolverObject<TResult, TParent, TContext, TArgs> {
  subscribe: SubscriptionSubscribeFn<any, TParent, TContext, TArgs>;
  resolve: SubscriptionResolveFn<TResult, any, TContext, TArgs>;
}

export type SubscriptionObject<TResult, TKey extends string, TParent, TContext, TArgs> =
  | SubscriptionSubscriberObject<TResult, TKey, TParent, TContext, TArgs>
  | SubscriptionResolverObject<TResult, TParent, TContext, TArgs>;

export type SubscriptionResolver<TResult, TKey extends string, TParent = {}, TContext = {}, TArgs = {}> =
  | ((...args: any[]) => SubscriptionObject<TResult, TKey, TParent, TContext, TArgs>)
  | SubscriptionObject<TResult, TKey, TParent, TContext, TArgs>;

export type TypeResolveFn<TTypes, TParent = {}, TContext = {}> = (
  parent: TParent,
  context: TContext,
  info: GraphQLResolveInfo
) => Types.Maybe<TTypes> | Promise<Types.Maybe<TTypes>>;

export type IsTypeOfResolverFn<T = {}, TContext = {}> = (obj: T, context: TContext, info: GraphQLResolveInfo) => boolean | Promise<boolean>;

export type NextResolverFn<T> = () => Promise<T>;

export type DirectiveResolverFn<TResult = {}, TParent = {}, TContext = {}, TArgs = {}> = (
  next: NextResolverFn<TResult>,
  parent: TParent,
  args: TArgs,
  context: TContext,
  info: GraphQLResolveInfo
) => TResult | Promise<TResult>;

/** Mapping between all available schema types and the resolvers types */
export type TResolversTypes = ResolversObject<{
  User: ResolverTypeWrapper<Types.User>; // <=========== this should be a `TUser`
  String: ResolverTypeWrapper<Types.Scalars['String']>;
  Query: ResolverTypeWrapper<{}>;
  Boolean: ResolverTypeWrapper<Types.Scalars['Boolean']>;
}>;

/** Mapping between all available schema types and the resolvers parents */
export type TResolversParentTypes = ResolversObject<{
  User: Types.User; // <=========== this should be a `TUser`
  String: Types.Scalars['String'];
  Query: {};
  Boolean: Types.Scalars['Boolean'];
}>;

export type TUserResolvers<ContextType = any, ParentType extends TResolversParentTypes['User'] = TResolversParentTypes['User']> = ResolversObject<{
  id?: Resolver<TResolversTypes['String'], ParentType, ContextType>;
  name?: Resolver<TResolversTypes['String'], ParentType, ContextType>;
  __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
}>;

export type TQueryResolvers<ContextType = any, ParentType extends TResolversParentTypes['Query'] = TResolversParentTypes['Query']> = ResolversObject<{
  getUser?: Resolver<Types.Maybe<TResolversTypes['User']>, ParentType, ContextType>;
}>;

export type TResolvers<ContextType = any> = ResolversObject<{
  User?: TUserResolvers<ContextType>;
  Query?: TQueryResolvers<ContextType>;
}>;

To Reproduce
Steps to reproduce the behavior:

https://github.com/Jonir227/graphql-codegen-import-type-bug

npm run grqphql

CSharp plugin argument classes not created

Describe the bug
There are not created argument classes when using c sharp plugin

To Reproduce
Extremely simple. Just compare homepage of this project (default is typescript in yml file ) to this for example

overwrite: true
schema: schema.graphql
generates:
RimacCmvdsClient.Models/Models.cs:
plugins:
- c-sharp
config:
namespaceName: e
scalars:
DateTime: DateTime

QuerySearchArgs is missing !

Sandbox has timeouts but reproducing this is trivial. Just on home page of this site use c-sharp plugin

  1. My GraphQL schema:
scalar Date

schema {
  query: Query
}

type Query {
  me: User!
  user(id: ID!): User
  allUsers: [User]
  search(term: String!): [SearchResult!]!
  myChats: [Chat!]!
}

enum Role {
  USER,
  ADMIN,
}

interface Node {
  id: ID!
}

union SearchResult = User | Chat | ChatMessage

type User implements Node {
  id: ID!
  username: String!
  email: String!
  role: Role!
}

type Chat implements Node {
  id: ID!
  users: [User!]!
  messages: [ChatMessage!]!
}

type ChatMessage implements Node {
  id: ID!
  content: String!
  time: Date!
  user: User!
}
  1. My GraphQL operations:
# Put your operations here
  1. My codegen.yml config file:
overwrite: true
schema: schema.graphql
generates:
  RimacCmvdsClient.Models/Models.cs:
    plugins:
      - c-sharp
    config:
        namespaceName: e
        scalars:
            DateTime: DateTime

Expected behavior
Created argument classes for arguments like in typescript plugin (classes with Args sufix)

Environment:

  • OS:
  • @graphql-codegen/...:
  • NodeJS: 14.15.4

Additional context

[urql] should respect omitOperationSuffix and typesPrefix options

Describe the bug
I am used to prefixing my operations with Q/M/S/F so I opted enabled option omitOperationSuffix. Unfortunately, the urql plugin doesn't consider that and uses wrong type names., Also for a reason, I like to prefix types with T which is ignored by plugin as well.

https://github.com/dotansimha/graphql-code-generator/blob/db1db14ad43bdd876b4eab053d41b074b872359c/packages/plugins/typescript/urql/src/visitor.ts#L87

To Reproduce
Steps to reproduce the behavior:

I tried to reproduce in codesandbox, but it's giving me weird errors: https://codesandbox.io/s/affectionate-montalcini-zcpsv?file=/codegen.yml

  1. My GraphQL schema:
type Query {
    user(id: ID!): User!
}

type User {
    id: ID!
    email: String!
}
  1. My GraphQL operations:
# Put your operations here
query user {
    user(id: 1) {
        id
        email
    }
}
  1. My codegen.yml config file:
# Put your YML here
schema: schema.graphql
documents: document.graphql
generates:
  types.ts:
    plugins:
      - typescript
      - typescript-operations
      - typescript-urql
    config:
      typesPrefix: T
      omitOperationSuffix: true
      withComponent: false
      withHooks: true

Expected behavior

The emitted types should not use operation type suffix when omitOperationSuffix is enabled. And typesPrefix should be respected.

Vue 3 support for TypeScript Vue Apollo

Is your feature request related to a problem? Please describe.

Currently, the TypeScript Vue Apollo imports @vue/composition-api which is a plugin to make the new Vue 3 composition API backward-compatible with Vue 2.

Describe the solution you'd like

This import is no longer needed with Vue 3, as the Composition API is now part of Vue itself.

I would like to see support for Vue 3, maybe with a new configuration parameter. I'm not sure if other changes besides changing this import are needed.

Additional context

Vue Appollo itself is being reworked for Vue 3: https://v4.apollo.vuejs.org/

Update C#-Operations Docs

Currently Enums are not properly serialized when the standard Newtonsoft Serializer is used.

Solution:

public sealed class GraphQLEnumConverter : StringEnumConverter
  {
    public GraphQLEnumConverter()
        : base(new PascalCaseNamingStrategy())
    {
    }
  }

  internal sealed class PascalCaseNamingStrategy : NamingStrategy
  {
    protected override string ResolvePropertyName(string name) => name;
  }

GQLClient = new GraphQLHttpClient(new GraphQLHttpClientOptions
      {
        EndPoint = new Uri(EndpointHttp)

      }, new NewtonsoftJsonSerializer(new JsonSerializerSettings
      {
        Converters = new List<JsonConverter>{
              new StringEnumConverter(new PascalCaseNamingStrategy())
          }
      }));

This should be added to the docs.

[typescript-operations] add description and @deprecated comments with preResolveTypes=true

Is your feature request related to a problem? Please describe.

We use preResolveTypes since I dont want the devs to accidentally use the graphql types witch happens quiet often recently (maybe an option to dont export them could also help here). I read recently that deprecations are added to the generated files via @deprecated comment. So Ive looked them up and found they are only added to the Graphql types but not to the operation types with preResolveTypes. Even more there are no comments added to the operation types.

Describe the solution you'd like
I think it would be a good Idea to also add them to the Operations or at least when preResolveTypes is true.

Describe alternatives you've considered
I have no idea. Description and deprecated could be very helpful.

External document import handling mismatch between `typescript-vue-apollo` and `typescript-vue-urql`

Describe the bug
While trying to share types between urql-vue and vue-apollo, there seems to be some mismatches in how data is being referenced.

The issue I'm seeing is when importing document types using

        documentMode: "external",
        importDocumentNodeExternallyFrom: "./graphql-documents"

typescript-vue-apollo will reference the document types in camelCase, while typescript-vue-urql on the other hand will use PascalCase. I can change the naming of the document file (which lets me satisfy either Vue or Urql), but I can't however find a way to override how it's being referenced from the other files.

Additionally, typescript-vue-urql will not reference the document types properly, as it does not add the required prefix (like vue-apollo does). I've tried setting documentVariablePrefix: "Operations.", but the generated code omits the trailing ., so it becomes OperationsUser instead of Operations.User.

(Also related: dotansimha/graphql-code-generator#6303 )

To Reproduce
See https://codesandbox.io/s/eloquent-pine-lqgjo?file=/graphql-urql.ts

rfc: react-query hooks with near-operation-file -like generation

Is your feature request related to a problem? Please describe.

n/a

Describe the solution you'd like

cc/ @dotansimha

the react-query plugin is a great idea. however, it's not tailored to my current workflow.

desired outcomes:

  • my-query.graphl => my-query.generated.ts // produces types via typescript-operations (done!)
  • my-query.graphl => my-query.hook.generated.ts // produces query hook locally, auto mapping IO/types into the hook

This is different than the status quo, where logic is bundled in a types+operations-types+logic file. The fetcher could still be shared via import mapping. Additionally, a thunk should be consider for providing endpoint datas, such that config can be provided by the application, vs the generation tool.

Describe alternatives you've considered

Living w/ the status quo impl.

Additional context

By isolating operations hooks, I can shave bundle sizes, and also have a more narrow focus when inspecting my queries.

Support for nested keyfields for Apollo-Client-Helpers

Is your feature request related to a problem? Please describe.
Looking at book typepolicy keyfields example from the apollo client docs https://www.apollographql.com/docs/react/caching/cache-configuration/#generating-unique-identifiers you can see there is support for nested fields. However the types that get generated from the apollo-client helpers don't seem to support this yet and gives an error where you try to use a nested keyfield.

Describe the solution you'd like

support for nested keyfields.

Apollo-Client Helpers looks like a great addition to the already amazing code generator 👍

[C# Operations] - add support for aliases

Describe the bug
For now generator use "type" to produce output property name. It should use alias instead.

To Reproduce

  1. Generate attached operations.

  2. See generated output - it generates 2 properties ("users") with the same name (C# syntax error).

  3. My GraphQL schema:

scalar Date

schema {
  query: Query
}

type Query {
  users(role: Role!): [User]
}

enum Role {
  USER,
  ADMIN,
}

union SearchResult = User

type User {
  id: ID!
  username: String!
  email: String!
  role: Role!
}
  1. My GraphQL operations:
query allUsers {
  users: users(role: USER) {
    ...UserFields
  }
  admins: users(role: ADMIN) {
    ...UserFields
  }
}

fragment UserFields on User {
  id
  username
}
  1. My codegen.yml config file:
generates:
  src/main/c-sharp/my-org/my-app/Operations.cs:
    plugins:
      - c-sharp-operations
    config:
      typesafeOperation: true

Expected behavior

  1. public System.Collections.Generic.List users { get; set; }
  2. public System.Collections.Generic.List admins { get; set; }
    In generated output.

Environment:

  • @graphql-codegen/c-sharp-operations:

Additional context

near-operation-file-preset: Cannot use flattenGeneratedTypes w/ fragments across files

Describe the bug
Using the flattenGeneratedTypes option (required to workaround dotansimha/graphql-code-generator#4212) causes GraphQL to fail to locate fragments when using near-operation-file-preset and the fragments are located in other files (regardless whether the queries are written in .graphql or .ts files w/ imports).

Similar to dotansimha/graphql-code-generator#528

To Reproduce
https://codesandbox.io/s/empty-fast-xl915?file=/codegen.yml

Expected behavior
Should compile fine with or without flattenGeneratedTypes.

Environment:
n/a

typescript-react-query getServerSideProps

Describe the bug

Using getKey function inside getServerSideProps will cause below error. It works as expect if passing null to it.

Error serializing .dehydratedState.queries[0].queryKey[1] returned from getServerSideProps in "/b".
Reason: undefined cannot be serialized as JSON. Please use null or omit this value.

Is it better to set a default value to getKey function as null? if not, when we use getQueryData after mutation without manually pass null to getKey function, it will not return the data

To Reproduce
Steps to reproduce the behavior:

  1. My GraphQL schema:
# Put your schema here
  1. My GraphQL operations:
# Put your operations here
  1. My codegen.yml config file:
# Put your YML here

Expected behavior

Environment:

  • OS: Mac
  • @graphql-codegen/...: 1.21.5
  • NodeJS: 14.16.1

Additional context

Enum is being treated as `string` in typescript mongodb plugin

Describe the bug

Enum is being treated as string in typescript mongodb plugin
To Reproduce
Steps to reproduce the behavior:

  1. Create a simple @entity with a @column with enum value.
  2. Generate the schema with typescript & typescript-mongodb plugin

Codesanbox link: Click here

My GraphQL schema:

enum Role {
    USER
    ADMIN
}

type User @entity {
    _id: ID! @id
    name: String! @column
    role: Role! @column
}

My codegen.yml config file:

schema: ./schema.graphql
config:
  enumsAsTypes: true
generates:
  ./mongodb-types.ts:
    plugins:
      - typescript-mongodb
      - typescript

Expected behavior

export type Maybe<T> = T | null;
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
import { ObjectID } from 'mongodb';
export type UserDbObject = {
  _id: ObjectID,
  name: string,
  role: string,  /*********** EXPECTED THIS TYPE TO BE ```Role``` TYPE *******/
};

/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
  ID: string;
  String: string;
  Boolean: boolean;
  Int: number;
  Float: number;
};

export type Role =
  | 'USER'
  | 'ADMIN';

export type User = {
  __typename?: 'User';
  _id: Scalars['ID'];
  name: Scalars['String'];
  role: Role;
};

export type AdditionalEntityFields = {
  path?: Maybe<Scalars['String']>;
  type?: Maybe<Scalars['String']>;
};

Environment:

  • OS: Windows 10 64 bit
  • @graphql-codegen/cli: 1.20.1
  • @graphql-codegen/typescript: 1.21.0
  • @graphql-codegen/typescript-mongodb: 1.19.3
  • NodeJS: 14.16.1

Additional context

I have tried only using typescript-mongodb plugin it doesn't even generate enums but when I use typescript plugin extra types are generated which is also I don't want for example:

type User @entity {
  name: String! @column
}

That will generate

export type UserDbObject = {
  name: string
};

and

export type User = {
  name: Scalars['String'];
};

I only want the upper one output.

import-types preset does not add import when documents is not set

Following scenario:

  • types are generated by typescript plugin into types.ts
  • resolvers are generated typescript-resolver into resolvers.ts
    • referencing types.ts using the import-types preset
    • the all type references re properly prefixed with Types
    • but the import statement is not added to the top of the file
      • `import * as Types from './types'

After reviewing the code of the import-types preset I think the issue is that the import is only added when the documents key is set:
https://github.com/dotansimha/graphql-code-generator/blob/22c1d235fb983f6b44059b8e9445ccdb85ad6bcf/packages/presets/import-types/src/index.ts#L67

To Reproduce
I have created a code sandbox to reproduce this issue:

Additional Info

Why separate types and resolvers:
The types in types.ts are shared between client and server. Hence resolver definitions shouldn't be contained in this file

Why not include document key in root:
Server and client execute different operations. Hence documents are provided on generator level individually.

Note:
For anyone finding this there is a workaround to get this working. One needs to use the add plugin to manually prepend the import statement. Please note that is in addition to using the import-types preset which ensures the types are all type usage is prefixed with Types.:

    preset: import-types
    presetConfig:
      typesPath: '@shared/types'
    plugins:
      - add:
          content: "import type * as Types from '@shared/types';"
      - typescript-resolvers

[typescript-react-apollo]: `importDocumentNodeExternallyFrom` omits `documentVariableSuffix`

I'm trying to figure out how to be able to generate separate files: one containing only types/operations/typed-document-nodes, and the other containing only react hooks. The goal is that then if a consuming package doesn't depend on react, it can specifically import the types and not have any errors since the react hooks are in a separate file, while minimizing the duplication of generated code/types.

(BTW, if there are better ways of doing this please let me know!)

For this, I am thinking of generating types/operations/typed-document-nodes in one file say types.ts, and then only react hooks in e.g. react.ts.

As a result, I need react.ts to import types and operations from types.ts to avoid duplicating types.

I can more or less approximate this by using:

documentMode: external
importDocumentNodeExternallyFrom: ./types

In the typescript-react-apollo config. However, this ends up referring to documents as e.g. Operations.SomeOperation instead of Operations.SomeOperationDocument which is how the document is named in types.ts. One workaround I can think of is setting documentVariableSuffix: "" in the configuration for types.ts, but this is not ideal as it's hacky and my code already references variables with the Document suffix.

I believe maybe the problem is because the seemingly-relevant code for typescript-react-apollo doesn't take into account any kind of suffix, such as this.config.documentVariableSuffix:

https://github.com/dotansimha/graphql-code-generator/blob/0538923f0cee884f95136b3ac794f83238cee568/packages/plugins/typescript/react-apollo/src/visitor.ts#L161-L165

I wonder if it should be something like Operations.${node.name?.value ?? ''}${this.config.documentVariableSuffix} instead?

Unable to load typescript-apollo-angular in codesandbox while attempting reproduce bug: serviceProvidedInRoot: false ignored

Bug Description

Unable to utilise codesandbox to reproduce a different bug. Any error is presented:
Unable to find template plugin matching 'typescript-apollo-angular'
The plugin has been selected and loaded from the package.json file.

The original bug I was attempting to reproduce, was that the config option: serviceProvidedInRoot: false is ignored by graphql-codegen

To Reproduce

Please see working demonstration of the bug here: https://codesandbox.io/s/agitated-fog-1j6kl?file=/codegen.yml

Expected Behaviour

  1. graphql-codegen should compile and run in the codesandbox instance
  2. Angular services generated by graphql-codegen should be generated with @Injectable() when serviceProvidedInRoot: false

Observed behaviour

  1. graphql-codegen does not finish compiling because of error message: ``
  2. Angular services are generated with @Injectable({ providedIn: 'root' }) even when serviceProvidedInRoot: false

TypeGraphQL Generator with Union type fails with error

Describe the bug

When generating TypeGraphQL, using a union type, the type passed to @TypeGraphQL.Field fails with the error: 'Step' only refers to a type, but is being used as a value here. (TS 2693)

To Reproduce
Steps to reproduce the behavior:

Run the generation below.

  1. My GraphQL schema:
type PullStep @entity {
  nextSteps: [Step!] @column
  # ...other fields...
}

type PushStep @entity {
  nextSteps: [Step!] @column
  # ...other fields...
}

union Step = PullStep | PushStep
  1. My codegen.yml config file:
generates:
  types.ts:
    plugins:
      - typescript-type-graphql
  1. The output:
import * as TypeGraphQL from 'type-graphql';
export { TypeGraphQL };
export type Maybe<T> = T | null;
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
export type FixDecorator<T> = T;
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
  ID: string;
  String: string;
  Boolean: boolean;
  Int: number;
  Float: number;
};

@TypeGraphQL.ObjectType()
export class PullStep {
  __typename?: 'PullStep';

  @TypeGraphQL.Field(type => [Step], { nullable: true })
  // ^^^^ !!! "'Step' only refers to a type, but is being used as a value here. (TS 2693)" !!!
  // ^^^^
  nextSteps!: Maybe<Array<Step>>;
};

@TypeGraphQL.ObjectType()
export class PushStep {
  __typename?: 'PushStep';

  @TypeGraphQL.Field(type => [Step], { nullable: true })
  // ^^^^ !!! "'Step' only refers to a type, but is being used as a value here. (TS 2693)" !!!
  // ^^^^
  nextSteps!: Maybe<Array<Step>>;
};

export type Step = PullStep | PushStep;

Expected behavior

No error. To fix this, it probably needs a union type generated:
https://typegraphql.com/docs/unions.html

Environment:

  • OS: Linux
  • @graphql-codegen/...: 1.21.3
  • NodeJS: 14

Additional context

Support tree shaking with typescript-graphql-request

Is your feature request related to a problem? Please describe.

The current implementation of getSdk exports queries, mutations, and subscriptions as a single object.

const defaultWrapper = sdkFunction => sdkFunction();
export function getSdk(client, withWrapper = defaultWrapper) {
  return {
    getBooks(variables, requestHeaders) {
      return withWrapper(() => client.request(GetBooksDocument, variables, requestHeaders))
    },
    getAuthors(variables, requestHeaders) {
      return withWrapper(() => client.request(GetAuthorsDocument, variables, requestHeaders))
    }
    // and many other methods
  }
}

const client = new Client()
const sdk = getSdk(client)
const res = await sdk.getBooks({ authorId })

This implementation does not support tree shaking.

I'm now using typescript-graphql-request with Next.js. The applications built with Next.js have multiple pages, so all of the sdk methods are imported from the all pages that uses it.

Describe the solution you'd like

My solution is like this.
This solution does not support withWrapper, but this is a trade-off.

export function getBooks(client, variables, requestHeaders) {
  return client.request(GetBooksDocument, variables, requestHeaders)
} 

export function getAuthors(client, variables, requestHeaders) {
  return client.request(GetAuthorsDocument, variables, requestHeaders)
}

// and many other functions

const client = new Client()
const res = await getBooks(client, { authorId })

In this example, only getBooks is imported and contribute to reduce bundle size.

Describe alternatives you've considered

Additional context

[Documentation] useMutation example for Vue Composition API

Describe the bug
Currently there's no example on how to use the useUpdateBooksMutation or something similar in the docs. It would be great if someone with knowledge could provide a simple example where loading, error onDone and mutation are used.

Additional context

Consider this mutation:

mutation {
  setViewerPreference(options: { language: "bb-bb" }) {
    language
  }
}

For this to work I created a file called setLanguage.graphql for graphql-codegen (a full options object as used in the Playground would've been better but I don't have that skill yet):

mutation setLanguage($language: String!) {
  setViewerPreference(options: { language: $language }) {
    language
  }
}

Using this in a component in Settings.vue looks like this:

<script lang="ts">
import { defineComponent, ref, watch } from '@vue/composition-api'
import { useSetLanguageMutation } from 'src/graphql/generated/operations'

export default defineComponent({
  setup(_, context) {
    const languageOptions = [
      { value: 'en-us', label: 'English' },
      { value: 'nl-be', label: 'Nederlands' },
    ]
    const language = ref(context.root.$i18n.locale)

    const { mutate, loading, error, onDone } = useSetLanguageMutation({
      variables: {
        language: 'ee-ee',
      },
    })

    watch(language, (newLanguage) => {
      context.root.$i18n.locale = newLanguage
      void mutate({ language: newLanguage })
    })

    return { language, languageOptions, }
  },
})
</script>

Questions/unclear

I don't understand why the function useSetLanguageMutation needs to be initialized with a variables value already? It would be great if one could just do this:

    const { mutate, loading, error, onDone } = useSetLanguageMutation()

    watch(language, (newLanguage) => {
      void mutate({ language: newLanguage })
    })

On a side note, when calling the mutate() function, the one that really executes the mutation, are the loading and other const returned by useSetLanguageMutation still usable?

I'm sorry for these stupid questions, but as you can see I'm a noob and would love to have a more detailed example or at least one example on how to properly use the useMutation generated by the graphql codegen. It would even be better if it would include an example on how to update the cache too, but this is of course out of scope for the codegen. I tried to follow this example but it's for react.

Thank you anyhow for reading this far.

[typescript-react-query] add documentMode support

Is your feature request related to a problem? Please describe.

We want to preprocess the document to remove duplicated fragments. For this we created a custom version of graphql tag witch works fine. But now we want to use the react-query plugin and can not enable graphql-tags with it.

Currently typescript-react-query forces the document-mode to "string".

Describe the solution you'd like

typescript-react-query should be able to use the document-modes the other plugins support.

Describe alternatives you've considered

It would be possible to fix our problem by make grpahql-code-gen dedup the fragments before generating the document, but I have no idea yet how to do so. Another way would be to preprocess the document when its done.

[Typescript React Apollo] Change variables of baseOptions to non optional when required

Versions

  • @graphql-codegen/cli: ^1.21.4
  • @graphql-codegen/typescript: ^1.22.0
  • @graphql-codegen/typescript-operations: ^1.17.16
  • @graphql-codegen/typescript-react-apollo: ^2.2.4

Schema

query getUser(id: ID!) {
  user(id: $id) {
    id
    name
    email
  }
}

Generated code

export function useGetUserQuery(baseOptions: Apollo.QueryHookOptions<IGetUserQuery, IGetUserQueryVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useQuery<IGetUserQuery, IGetUserQueryVariables>(GetUserDocument, options);
}

React Code

const Foo = () => {
    const case1 = useGetUserQuery(); // compile time error (because baseOptions are not provided)
    const case2 = useGetUserQuery({}); // run time error (because baseOptions.variables are not provided)
    const case3 = useGetUserQuery({ variables: { id: 'BAR' } }); // good
};

I think making case2 compile time error is better than runtime error.
So, I tried to find any options for this, but I couldn't

Suggestions

  • Make VariableRequiredQueryHookOptions interface
  • And use the interface as baseOptions type when variables required query

Feature: Generated code

interface VariableRequiredQueryHookOptions<Query, Variables> extends Apollo.QueryHookOptions<Query, Variables> {
    variables: Variables;
}

export function useGetUserQuery(baseOptions: VariableRequiredQueryHookOptions<IGetUserQuery, IGetUserQueryVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return Apollo.useQuery<IGetUserQuery, IGetUserQueryVariables>(GetUserDocument, options);
}

typescript-react-apollo: Invalid TypeScript output when both withHOC and useTypeImports are true

Describe the bug

When using typescript-react-apollo plugin, and enabling both withHOC and useTypeImports output is not a valid TypeScript file:

import * as ApolloReactHoc from '@apollo/client/react/hoc';
import type * as ApolloReactHoc from '@apollo/client/react/hoc';

To Reproduce
Steps to reproduce the behavior:

  1. Open live-demo
  2. Choose the Operations types template
  3. Change the config to one below
  1. My GraphQL schema:
# Default from demo
  1. My GraphQL operations:
# Default from demo
  1. My codegen.yml config file:
generates:
  types-and-hooks.tsx:
    config:
      withHOC: true
      useTypeImports: true
    plugins:
      - typescript
      - typescript-react-apollo

Expected behavior

Only this line should be in the output:

import * as ApolloReactHoc from '@apollo/client/react/hoc';

Actual behavoir
Both lines are in the output:

import * as ApolloReactHoc from '@apollo/client/react/hoc';
import type * as ApolloReactHoc from '@apollo/client/react/hoc';

Environment:
Using the live-demo reproduces it

  • OS:
  • @graphql-codegen/...:
  • NodeJS:

Additional context

How to use both near-operation-file-preset and import-types-preset with typescript and react

I want to generate typing declear once in single file and other files just import its type from it when i start working with react,typescript and graphql

Although near-operation-file-preset generates a file per each operation file,every file repeats typing declear. And import-types-preset helps import types from file but it can not generate files like near-operation-file-preset .
One more thing is that near-operation-file-preset contains both types and components ,while splited to single file may be better i think.

What I want may look like this:

graphql
|--test1.graphql  // query and mutations
|--test1.generated.tsx  // components and hooks without types
|--test2.graphql  
|--test2.generated.tsx
|--types.ts   // types

But I find it's hard to work with both.

overwrite: true
schema: './schema.graphql'
documents: 'src/**/*.graphql'
generates:
  src/graphql/types.tsx:
    - typescript
  src/graphql/:
    preset:
      # near-operation-file
      import-types
    presetConfig:
      # extension: .generated.tsx
      # baseTypesPath: types.ts
      typesPath: types.ts
    plugins:
      - time:
        format: DD.MM.YY
        message: 'The file generated in: '
      - typescript
      - typescript-operations
      - typescript-react-apollo
    config:
      withHOC: true
      withHooks: true
      skipTypename: true

Does anyone can help me ?
Thanks a lot!

[import-types-preset] Types should be imported only when the are external to the generated file

It seems import-types preset adds "Types." prefix to all types, regardless if they actualy need to be imported.

Codegen config:

generates:
    src/api/index.ts:
        schema: './node_modules/@foo/graphql-schema/schema.graphql'
        documents: './queries.graphql'
        preset: import-types
        presetConfig:
            typesPath: '@foo/graphql-schema'
        plugins:
            - typescript-operations
            - typescript-react-apollo
        config:
            withHooks: true

Types for the schema (i.e. those generated by typescript plugin) and the schema itself are in package @foo/graphql-schema. Code generated by typescript-operations is ok, it contains typed GraphQL operations specified in queries.graphql and uses types imported from @foo/graphql-schema. But the code generated by typescript-react-apollo also tries to import stuff - but it shouldn't, as types for queries are defined right next to it, e.g.:

import * as Types from '@foo/graphql-schema';

// ...

// `SocialMediaLinks` is imported from `Types`, good
export type GetFooterDataQuery = { __typename?: 'Query' } & {
    socialMediaLinks?: Types.Maybe<
        Array<Types.Maybe<{ __typename?: 'SocialMediaLinks' } & Pick<Types.SocialMediaLinks, 'title' | 'type' | 'url'>>>
    >;
};

// ...

// oh no, `GetFooterDataQuery` doesn't exist on `Types`!
export function useGetFooterDataQuery(
    baseOptions?: Apollo.QueryHookOptions<Types.GetFooterDataQuery, Types.GetFooterDataQueryVariables>,
) {
    const options = { ...defaultOptions, ...baseOptions };
    return Apollo.useQuery<Types.GetFooterDataQuery, Types.GetFooterDataQueryVariables>(GetFooterDataDocument, options);
}

For now I think I solved it by splitting the generation in two steps, first generate types for operations, and then generate Apollo hooks using import-plugin once again, but importing the types generated in the first step - I assume that it's okay, because typescript-react-apollo doesn't actually need the schema types?

2 Java tests failing on master on Windows

Describe the bug
The "Should produce valid Java code" and "Should use the correct package name by default" tests are failing without any changes.

To Reproduce
Steps to reproduce the behavior:

yarn
yarn build
yarn test

Expected behavior

All tests passing.

Environment:

  • OS: Windows 10
  • @graphql-codegen/...: I checked out master
  • NodeJS: 10.15.1

Additional context

Output of yarn test:

$ yarn test
yarn run v1.9.4
$ lerna run test --ignore @graphql-codegen/live-demo --ignore @graphql-codegen/website
lerna notice cli v3.18.3
lerna notice filter excluding ["@graphql-codegen/live-demo","@graphql-codegen/website"]
lerna info filter [ '!@graphql-codegen/live-demo', '!@graphql-codegen/website' ]
lerna info Executing command in 30 packages: "yarn run test"
lerna info run Ran npm script 'test' in '@graphql-codegen/plugin-helpers' in 1.9s:
$ jest --config ../../../jest.config.js
lerna info run Ran npm script 'test' in '@graphql-codegen/core' in 2.3s:
$ jest --config ../../jest.config.js
lerna info run Ran npm script 'test' in '@graphql-codegen/fragment-matcher' in 2.7s:
$ jest --config ../../../../jest.config.js
lerna info run Ran npm script 'test' in '@graphql-codegen/introspection' in 2.3s:
$ jest --config ../../../../jest.config.js
lerna info run Ran npm script 'test' in '@graphql-codegen/relay-operation-optimizer' in 2.7s:
$ jest --config ../../../../jest.config.js
lerna info run Ran npm script 'test' in '@graphql-codegen/schema-ast' in 2.8s:
$ jest --config ../../../../jest.config.js
lerna info run Ran npm script 'test' in '@graphql-codegen/visitor-plugin-common' in 2.9s:
$ jest --config ../../../../jest.config.js
lerna info run Ran npm script 'test' in '@graphql-codegen/typescript-graphql-files-modules' in 2.6s:
$ jest --config ../../../../jest.config.js
lerna info run Ran npm script 'test' in '@graphql-codegen/cli' in 6.1s:
$ jest --config ../../jest.config.js
lerna info run Ran npm script 'test' in '@graphql-codegen/flow' in 4.9s:
$ jest --config ../../../../jest.config.js
lerna info run Ran npm script 'test' in '@graphql-codegen/java-apollo-android' in 5.0s:
$ jest --config ../../../../jest.config.js
lerna ERR! yarn run test exited 1 in '@graphql-codegen/java'
lerna ERR! yarn run test stdout:
$ jest --config ../../../../jest.config.js
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

lerna ERR! yarn run test stderr:
ts-jest[config] (WARN) TypeScript diagnostics (customize using `[jest-config].globals.ts-jest.diagnostics` option):
message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript confi
guration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecm
ascript-module-interoperability for more information.
FAIL tests/java.spec.ts
  Java
    × Should produce valid Java code (617ms)
    Config
      × Should use the correct package name by default (4ms)
      √ Should use the package name provided from the config (2ms)
    Enums
      √ Should add imports that are relevant to enums (1ms)
      √ Should generate basic enums correctly (2ms)
      √ Should allow to override enum values with custom values (1ms)
    Input Types / Arguments
      √ Should generate arguments correctly when using Array (3ms)
      √ Should generate input class per each type with field arguments (3ms)
      √ Should generate input class per each query with arguments (3ms)
      √ Should generate input class per each input, also with nested input types (2ms)

  ● Java › Should produce valid Java code

    Invalid Java code:
    line 1:11 token recognition error at: '\'
    line 1:16 token recognition error at: '\'
    line 1:12 mismatched input 'java' expecting ';'
    line 3:0 extraneous input 'import' expecting {<EOF>, 'abstract', 'class', 'enum', 'final', 'interface', 'private', 'protected', 'publ
ic', 'static', 'strictfp', ';', '@'}
    line 4:0 extraneous input 'import' expecting {<EOF>, 'abstract', 'class', 'enum', 'final', 'interface', 'private', 'protected', 'publ
ic', 'static', 'strictfp', ';', '@'}
    line 5:0 extraneous input 'import' expecting {<EOF>, 'abstract', 'class', 'enum', 'final', 'interface', 'private', 'protected', 'publ
ic', 'static', 'strictfp', ';', '@'}
    line 6:0 extraneous input 'import' expecting {<EOF>, 'abstract', 'class', 'enum', 'final', 'interface', 'private', 'protected', 'publ
ic', 'static', 'strictfp', ';', '@'}

      13 |     const mergedErrors = collectedErrors.join('\n');
      14 |
    > 15 |     throw new Error(`Invalid Java code:\n${mergedErrors}`);
         |           ^
      16 |   }
      17 | }
      18 |

      at Object.validateJava (../common/tests/validate-java.ts:15:11)
      at Object.it (tests/java.spec.ts:68:5)

  ● Java › Config › Should use the correct package name by default

    expect(received).toContain(expected) // indexOf

    Expected substring: "package com.java.generated;"
    Received string:    "package com\\java\\generated;·
    import java.util.HashMap;
    import java.util.Map;
    import java.util.List;
    import java.util.stream.Collectors;·
    public class Types {···
      public static class InputWithArrayInput {
        private Iterable<String> _f;
        private Iterable<SearchUserInput> _g;···
        public InputWithArrayInput(Map<String, Object> args) {
          if (args != null) {
            this._f = (Iterable<String>) args.get(\"f\");
            this._g = ((List<Map<String, Object>>) args.get(\"g\")).stream().map(SearchUserInput::new).collect(Collectors.toList());     
          }
        }···
        public Iterable<String> getF() { return this._f; }
        public Iterable<SearchUserInput> getG() { return this._g; }
      }
      public static class MetadataSearchInput {
        private Integer _something;···
        public MetadataSearchInput(Map<String, Object> args) {
          if (args != null) {
            this._something = (Integer) args.get(\"something\");
          }
        }···
        public Integer getSomething() { return this._something; }
      }
      public static class QueryUserArgs {
        private Object _id;···
        public QueryUserArgs(Map<String, Object> args) {
          if (args != null) {
            this._id = (Object) args.get(\"id\");
          }
        }···
        public Object getId() { return this._id; }
      }
      public static class QuerySearchUserArgs {
        private SearchUserInput _searchFields;···
        public QuerySearchUserArgs(Map<String, Object> args) {
          if (args != null) {
            this._searchFields = new SearchUserInput((Map<String, Object>) args.get(\"searchFields\"));
          }
        }···
        public SearchUserInput getSearchFields() { return this._searchFields; }
      }
      public enum ResultSort {
        Asc(\"ASC\"),
        Desc(\"DESC\");·····
        public final String label;······
        ResultSort(String label) {
          this.label = label;
        }·····
        private static final Map<String, ResultSort> BY_LABEL = new HashMap<>();·······
        static {
            for (ResultSort e : values()) {
                BY_LABEL.put(e.label, e);
            }
        }·····
        public static ResultSort valueOfLabel(String label) {
          return BY_LABEL.get(label);
        }
      }···
      public static class SearchUserInput {
        private String _username;
        private String _email;
        private String _name;
        private ResultSort _sort;
        private MetadataSearchInput _metadata;···
        public SearchUserInput(Map<String, Object> args) {
          if (args != null) {
            this._username = (String) args.get(\"username\");
            this._email = (String) args.get(\"email\");
            this._name = (String) args.get(\"name\");
            this._sort = (ResultSort) args.get(\"sort\");
            this._metadata = new MetadataSearchInput((Map<String, Object>) args.get(\"metadata\"));
          }
        }···
        public String getUsername() { return this._username; }
        public String getEmail() { return this._email; }
        public String getName() { return this._name; }
        public ResultSort getSort() { return this._sort; }
        public MetadataSearchInput getMetadata() { return this._metadata; }
      }
      public static class UserFriendsArgs {
        private Integer _skip;
        private Integer _limit;···
        public UserFriendsArgs(Map<String, Object> args) {
          if (args != null) {
            this._skip = (Integer) args.get(\"skip\");
            this._limit = (Integer) args.get(\"limit\");
          }
        }···
        public Integer getSkip() { return this._skip; }
        public Integer getLimit() { return this._limit; }
      }
      public enum UserRole {
        Admin(\"ADMIN\"),
        User(\"USER\"),
        Editor(\"EDITOR\");·····
        public final String label;······
        UserRole(String label) {
          this.label = label;
        }·····
        private static final Map<String, UserRole> BY_LABEL = new HashMap<>();·······
        static {
            for (UserRole e : values()) {
                BY_LABEL.put(e.label, e);
            }
        }·····
        public static UserRole valueOfLabel(String label) {
          return BY_LABEL.get(label);
        }
      }···
    }
    "

      73 |       const result = await plugin(schema, [], {}, { outputFile: OUTPUT_FILE });
      74 |
    > 75 |       expect(result).toContain(`package com.java.generated;`);
         |                      ^
      76 |     });
      77 |
      78 |     it('Should use the package name provided from the config', async () => {

      at Object.it (tests/java.spec.ts:75:22)

Test Suites: 1 failed, 1 total
Tests:       2 failed, 8 passed, 10 total
Snapshots:   0 total
Time:        3.373s, estimated 7s
Ran all test suites.
error Command failed with exit code 1.

lerna ERR! yarn run test exited 1 in '@graphql-codegen/java'
lerna WARN complete Waiting for 2 child processes to exit. CTRL-C to exit immediately.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

option to generate only one file using near-operation-file

We have a monorepo project structure with react code in a separate package and client state in a separate package.

packages
   client-react/
        src/
            generated-model.tsx
   client-state/
        src/
            generated-model.ts

So we would like to generate .tsx types in react package and rest in client state. And we want to add the baseTypes generated in client state as follows in the generated .tsx file in react package.

          /* tslint:disable */
          import { AddCounterStateMutation, AddCounterStateMutationVariables, AddCounterMutation,
          AddCounterMutationVariables, CounterStateQuery, CounterStateQueryVariables,CounterQueryQueryVariables,
          CounterQueryQuery, OnCounterUpdatedSubscription, OnCounterUpdatedSubscriptionVariables,
           } from '@project/client-state'

The feature request is almost close to near-operation-file preset but instead of generated files for each operation, we want only one file generated in the client-react package and import any required types from client-state based on baseType location (or package import).

Right now we manually update add section when generating .tsx file react package as follows

overwrite: true
schema: "./servers/backend-server/generated-schema.graphql"
generates:
  typings/graphql.d.ts:
    plugins:
      - typescript-graphql-files-modules
  packages/client-state/src/generated-models.ts:
    schema: "packages/client-state/src/**/*.graphql"
    documents: "packages/client-state/src/**/*.gql"
    config:
        noNamespaces: true
        contextType: ./interfaces/context#MyContext
        withMutationFn: false
        withHOC: false
        withComponent: false
    plugins:
      - add: |
          /* tslint:disable */
      - typescript
      - typescript-operations
      - typescript-resolvers
      - typescript-react-apollo
  packages/client-react/src/generated-model.tsx:
    schema: "packages/client-state/src/**/*.graphql"
    documents: "packages/client-state/src/**/*.gql"
    config:
      withMutationFn: true
      withHOC: true
      withComponent: true
    plugins:
      - add: |
          /* tslint:disable */
          import { AddCounterStateMutation, AddCounterStateMutationVariables, AddCounterMutation,
          AddCounterMutationVariables, CounterStateQuery, CounterStateQueryVariables,CounterQueryQueryVariables,
          CounterQueryQuery, OnCounterUpdatedSubscription, OnCounterUpdatedSubscriptionVariables,
           } from '@project/client-state'
      - typescript-react-apollo

Let me know if this something you would like to add a feature?

React Form Typescript Plugin

Forms are the majority of the front end work in a lot of applications. Graphql Schemas provide everything we need to generate the form.

Some tooling exists for doing similar things. EG: uniform.tools and a few other dead packages that attempt to do this at runtime.

IMO generating the forms would be a much better approach.

Formik is a very popular react form library with support for typescript, validation, and nested objects.

A form generation plugin is tricky because it needs to be customizable enough to suit peoples needs, with regards to styles and implementations of inputs, as well as validation, and hidden elements. The way formik is built provides an easy (ish) path to code generation, because it uses context for values, change handlers, metadata, etc...

The plugin should generate a "base" input for each built in scalar. Then Input Object types, and lists can be recursively composed from the base inputs.

Lists should be their own component as well, with an delete for each button in the list, and an add button at the end.

Circular references for Input Types can be handled by an Add <InputTypeName>.

Customization could be handled by generating a context Provider, which allows over rides for scalar types.

EG of a simple output

mutation myMutation (username: String!, $id: ID!) {
  updateMyUserName(username: $username, id: $id) {
    username
    id
  }
}
// generatedCode.tsx
import React, { createContext, useContext } from 'React'
export const StringInput = (originalProps) => {
   const inputContext = useContext(myMutationContext);
   const { label, ...props } = originalProps;
   const [field, meta] =  useField(props);
   if(inputContext.String) return <inputContext.String {...originalProps} />
   return (
     <>
       <label htmlFor={props.id || props.name}>{label}</label>
       <input className="text-input" {...field} {...props} />
       {meta.touched && meta.error ? (
         <div className="error">{meta.error}</div>
       ) : null}
     </>
   );
 };
 
 export const IDInput = (originalProps) => {
   const inputContext = useContext(myMutationContext);
   const { label, ...props } = originalProps;
   const [field, meta] =  useField(props);
   if(inputContext.ID) return <inputContext.ID {...originalProps} />
   return (
     <>
       <label htmlFor={props.id || props.name}>{label}</label>
       <input className="text-input" type="number" {...field} {...props} />
       {meta.touched && meta.error ? (
         <div className="error">{meta.error}</div>
       ) : null}
     </>
   );
 };

export const myMutationContext = createContext<{[key: ScalarNames]: React.Component}>({})

 export const MyMutationForm = (props: {onSubmit: () => unknown } ) =>{
    return (
      <Formik onSubmit={onSubmit}>
        <Form>
          <StringInput name="username" />
          <IntInput name="id" />
        </Form>
      </Formik>
    )
 }

example usage

import React from 'react'
import {myMutationContext , MyMutationForm } from './generated' 

export const MyComponent () {
  return (
    <myMutationContext.Provider context={{
        ID: MyCustomIDLookupComponent
      }} >
      <MyMutationForm  onSubmit={(formValues) => console.log({formValues}) } />
     </myMutationContext.Provider />
    )
}

Additionally, default types, and basic yup validations could also be generated.

MongoDB Plugin: Allow discriminatorField to be empty

It'd be great to allow discriminatorField to be empty for the abstractEntity/union directives. In many cases determining type by property checking is sufficient.

What happens currently is:

  • For abstractEntity an error is thrown by codegen
  • For union an { undefined: string } property is added to the union type.

[typescript-graphql-request] importOperationTypesFrom does nothing

Describe the bug
The docs for typescript-graphql-request describe that importOperationTypesFrom could be used to import the operations from another file. But whatever I do, it seems to do nothing.

To Reproduce
Codesandbox: https://codesandbox.io/s/boring-paper-rsces?file=/codegen.yml

Additional context
I made it work with this snipped. Bu I think importOperationTypesFrom should do that for me.

plugins:
  - add:
      content: "import * as Types from './types';"
  - typescript-graphql-request
config:
  typesPrefix: Types.

[C# operations] - generates duplicate classes

Describe the bug
When more properties of the same type are included in the same query/mutation, generator outputs duplicated classes with the same name in result cs file

To Reproduce

  1. Include more fields with the same non-primitive type but different name in the schema

  2. Make query/mutation to return all of the fields with the same type

  3. Generate result cs file
    Using example data in this issue, it generates TestSelection class 2-times in the same subclass which results to syntax error in C#.

  4. My GraphQL schema:

scalar Date

schema {
  query: Query
}

type Query {
  me: User!
  another: User!
  user(id: ID!): User
  allUsers: [User]
  search(term: String!): [SearchResult!]!
  myChats: [Chat!]!
}

enum Role {
  USER,
  ADMIN,
}

interface Node {
  id: ID!
}

union SearchResult = User | Chat | ChatMessage

type User implements Node {
  id: ID!
  username: String!
  email: String!
  role: Role!
  test1: Test!
  test2: Test!
}

type Test{
  id: ID!
  message: String!
}

type Chat implements Node {
  id: ID!
  users: [User!]!
  messages: [ChatMessage!]!
}

type ChatMessage implements Node {
  id: ID!
  content: String!
  time: Date!
  fromUser: User!
  toUser: User!
}
  1. My GraphQL operations:
query findUser($userId: ID!) {
  user(id: $userId) {
    ...UserFields
  }
}

fragment UserFields on User {
  id
  username
  role
  test1{
      id
  }
  test2{
      id
  }
}
  1. My codegen.yml config file:
generates:
  src/main/c-sharp/my-org/my-app/Operations.cs:
    plugins:
      - c-sharp-operations
    config:
      typesafeOperation: true

Expected behavior
"Selection" classes should be named by fieldName instead of fieldType =>

  1. public class Test1Selection
  2. public class Test2Selection

Environment:

  • @graphql-codegen/c-sharp-operations:

[typescript-react-apollo] `dedupeOperationSuffix` doesn't work when operation name is all upper case

Describe the bug

The typescript-react-apollo plugin doesn't properly handle deduping operation suffix when the suffix is all upper case.

To Reproduce

Generate apollo typescript hooks with an operation name that is all caps and post-fixed with QUERY, MUTATION, or FRAGMENT.

  1. My GraphQL schema:
type Query {
    user(id: ID!): User!
}

type User {
    id: ID!
    username: String!
    email: String!
}
  1. My GraphQL operations:
query GET_USER_QUERY {
    user(id: 1) {
        id
        username
        email
    }
}
  1. My codegen.yml config file:
config:
  apolloClientVersion: 3
  dedupeOperationSuffix: true
  namingConvention:
    transformUnderscore: true
documents:
  - './src/**/*.graphql'
generates:
  src/graphql/types-and-hooks.ts:
    schema: schema.graphql
    plugins:
      - 'typescript'
      - 'typescript-operations'
      - 'typescript-react-apollo'

Expected behavior

A hook should be generated with pascal case without duplicate operation name suffix

export function useGetUserQuery(baseOptions?: ApolloReactHooks.QueryHookOptions<GetUserQuery, GetUserQueryVariables>) {
        const options = {...defaultOptions, ...baseOptions}
        return ApolloReactHooks.useQuery<GetUserQuery, GetUserQueryVariables>(GetUserQueryDocument, options);
      }

Environment:

  • OS: MacOS 11.3
  • "@graphql-codegen/cli": "^1.21.3",
  • "@graphql-codegen/typescript": "^1.21.1",
  • "@graphql-codegen/typescript-operations": "^1.17.15",
  • "@graphql-codegen/typescript-react-apollo": "^2.2.4",
  • NodeJS: 12

Additional context

From looking at the codebase, I believe that the operation name being tested here should either be a regex match or convert it to test the operation name via pascalCase(name).includes(...).

Preset import-types not importing typescript-operations in all my files

Describe the bug
I have a monorepo with a root codegen.yml including this:

generates:
  packages/api/src/types/common.ts:
    plugins:
      - 'typescript'
      - 'typescript-operations'
  packages/api/src/types/models.ts:
    preset: import-types
    presetConfig:
      typesPath: './common'
    plugins:
      - 'typescript-react-apollo'
      - 'fragment-matcher'
  packages/api/src/types/auth-models.ts:
    preset: import-types
    presetConfig:
      typesPath: './common'
    plugins:
      - 'typescript-graphql-request'
      - 'fragment-matcher'

In packages/api/src/types/models.ts, the operation's types are well imported from './common' (Types.InterfaceX)
But in packages/api/src/types/auth-models.ts, the operation's types are not prefixed by 'Types.' so it doesn't find them... Why is there a difference between those 2 files please ?
(If I only put the typescript's pluggin in the common file and let the typescript-operations in the specifics files, the types are well imported from common in both files...)

goodfile badfile

To Reproduce
Steps to reproduce the behavior:

Generate types with 'typescript' and 'typescript-operations' pluggins in one file.
Generate types with 'typescript-graphql-request' pluggin using "preset: import-types" and "presetConfig: typesPath: './path/to/common/file'"

Expected behavior
To have my 'typescript-operations' types imported from my common file in both specific files ('Types.CommonType' instead of 'CommonType').

Environment:

  • OS: macOS 11.0.1
  • NodeJS: 14.15.1
  • "@graphql-codegen/fragment-matcher": "2.0.1",
    "@graphql-codegen/import-types-preset": "1.18.1",
    "@graphql-codegen/introspection": "1.18.1",
    "@graphql-codegen/typescript": "1.19.0",
    "@graphql-codegen/typescript-graphql-files-modules": "1.18.1",
    "@graphql-codegen/typescript-graphql-request": "2.0.3",
    "@graphql-codegen/typescript-operations": "1.17.12",
    "@graphql-codegen/typescript-react-apollo": "2.2.1":

Additional information
I also tried to add config 'importOperationTypesFrom' for @graphql-codegen/typescript-graphql-request but that didn't generate anything different...

Thank you very much !

Specific `namingConvention` option for `typescript-react-apollo` generated documents

Is your feature request related to a problem? Please describe.
We would like to have a specific naming convention for documents generated by typescript-react-apollo.

Right now they fall under the category typeNames when it comes to the namingConvention config. So for example we cannot use SCREAMING_SNAKE_CASE for documents (constants), but keeping PascalCase for types.

Describe the solution you'd like
I would propose having a 3rd key available for namingConvention. So it would be typeNames, enumValues AND documents (for example)

Describe alternatives you've considered
Just keeping the same naming convention for documents and types. It breaks our style guideline, still it is not a showstopper.

java-apollo-android fails due to forced enum CustomType

Describe the bug
1.
CustomType is always generated even if no scalar is in schema. The enum definition fails because it implements com.apollographql.apollo.api.ScalarType . Which is not fullfilled.

Defining a scalar results in another error because javaType returns: any.class which does not exist in java and is typescript specific

To Reproduce
Just a simple schema definition with and without scalar definition

Additional context
I could not find a way to disable CustomTypeVisitor yet and also I do not know how to define the java types in configuration for a scalar definition

[Flow] wrong type of nullable operation using inline fragments (union)

Describe the bug
There is a query operation with nullable return type (graphql interface). It uses graphql inline fragments (union) based on two types implementing the interface. In result of graphql code generation to flow types first branch of the union is marked as maybe type, but second one is not. See below repository and instructions for more details.

To Reproduce
Steps to reproduce the behavior:
There is a repository prepared for reproduction. You can just review the code or re-run codegen script on your own.

  1. My GraphQL schema:
type Query {
  getEntity: Entity # the key moment return type is nullable
}

interface Entity {
  field: String!
}

type SubEntityA implements Entity {
  field: String!
  subEntityFieldA: String!
}

type SubEntityB implements Entity {
  field: String!
  subEntityFieldB: String!
}
  1. My GraphQL operations:
  fragment SubEntityFragment on Entity {
    ... on SubEntityA {
      subEntityFieldA
    }
    ... on SubEntityB {
      subEntityFieldB
    }
  }

  query getEntity {
    data: getEntity {
      ...SubEntityFragment
      field
    }
  }
  1. My codegen.yml config file:
schema: ./schema.graphql
documents:
  - ./query.js
generates:
  ./graphql.types.js:
    plugins:
      - flow
      - flow-operations
    config:
      preResolveTypes: true

Expected behavior

It is expected that all branches of generated query type would be marked as maybe types.

Environment:

  • OS: MacOS Big Sur version 11.12.3, Windows 10
  • @graphql-codegen/add: 2.0.2
  • @graphql-codegen/cli: 1.21.3
  • @graphql-codegen/flow: 1.18.5
  • @graphql-codegen/flow-operations: 1.18.7
  • NodeJS: v12.13.0

Missing HOC suffix dedup leads to invalid generated types with `dedupeOperationSuffix` and `withHOC` options.

Describe the bug

The HOC generics are missing a name deduplication... https://github.com/dotansimha/graphql-code-generator/blob/0538923f0cee884f95136b3ac794f83238cee568/packages/plugins/typescript/react-apollo/src/visitor.ts#L181

So it generates:

export type GetUserInformationQueryVariables = Types.Exact<{ [key: string]: never; }>;

export type GetUserInformationQuery = (
// ...
);

// ...
export type GetUserInformationQueryProps<TChildProps = {}, TDataName extends string = 'data'> = {
      [key in TDataName]: ApolloReactHoc.DataValue<GetUserInformationQueryQuery, GetUserInformationQueryQueryVariables>
    } & TChildProps;

GetUserInformationQueryQuery, GetUserInformationQueryQueryVariables should be GetUserInformationQuery, GetUserInformationQueryVariables

To Reproduce

If a live reproduction is necessary I can create one.

  1. My GraphQL schema:
# Put your schema here
  1. My GraphQL operations:
# Put your operations here
  1. My codegen.yml config file:
# ...
        preset: near-operation-file
        presetConfig:
            extension: .generated.tsx
            baseTypesPath: webapp_gql.ts
        plugins:
            - typescript-operations
            - typescript-react-apollo
        config:
            reactApolloVersion: 2
            withHooks: true
            withHOC: true
            withComponent: true
            gqlImport: graphql.macro#gql
            dedupeFragments: true
            dedupeOperationSuffix: true
            exportFragmentSpreadSubTypes: true

Expected behavior

GetUserInformationQueryQuery, GetUserInformationQueryQueryVariables should be GetUserInformationQuery, GetUserInformationQueryVariables

Generics should dedup when HOC is enabled.

Environment:

  • OS: macOS
  • @graphql-codegen/...: latest
  • NodeJS: v14

Additional context

Happy to add more context, but I believe I found the broken line.

[React Query] option to allow responses with both { data: TData, errors?: Array<TError> }

Loving the react-query codegen plugin, thank you very much!

As we know, graphql returns { data, errors } -- the custom fetcher seems to force us to resolve just data or throw just errors, but we could have some successful data, and maybe one field resolver error.

Is it possible for this to be an option so we can see successful data as well as errors? I only throw if !!errors && data === null , or maybe i never even want to throw if its a 200 from graphql (aside from bad input, invalid auth, timeout, etc.)

Or is it even possible for the generated code to determine the return types from the custom fetcher?

[typescript-vue-apollo][withCompositionFunctions] Accept readonly types for variables types

Is your feature request related to a problem? Please describe.

We use the composition functions generated with typescript-vue-apollo with withCompositionFunctions config flag. We also use readonly types in parts of the codebase.

Currently, when we want to feed a readonly type as a variable to such generated composition function, we have to cast it or otherwise copy readonly types to mutable types, because the composition function's type expects mutable values.

Describe the solution you'd like

Preferably, the generated useQuery composition functions would accept both readonly and mutable types as variables and options props, as the assumption is that VueApolloComposable.useQuery should not mutate those values.

Describe alternatives you've considered

Currently, we have to cast the readonly values to mutable types when feeding them to the generated useQuery function, otherwise TypeScript raises error.

[typescript-type-graphql] Plugin to include GQL description in TypeGraphQL decorator description

Is your feature request related to a problem? Please describe.

It is mandated in our codebase that typegraphql types specify their description. GraphQL specifies a description syntax: https://spec.graphql.org/June2018/#sec-Descriptions. But those descriptions do not make it into the TypeGraphQL decorator, but instead as a code comment. I also see no option for this.

e.g.

"""
User description
"""
type User implements Node {
  "ID for the object"
  id: ID!
}

becomes

/** User description */
@TypeGraphQL.ObjectType({ implements: Node })
export class User extends Node {
  __typename?: 'User';
  /** ID for the object */

  @TypeGraphQL.Field(type => TypeGraphQL.ID)
  id!: Scalars['ID'];
};

I would like it to become

@TypeGraphQL.ObjectType({ 
    description: "User description",
    implements: Node
})
export class User extends Node {
  __typename?: 'User';

  @TypeGraphQL.Field(type => TypeGraphQL.ID, {description: "ID for the object"})
  id!: Scalars['ID'];
};

Describe the solution you'd like
Add a plugin option such as includeDescriptionInDeclaration that will put the description here. Defaults to false for backwards compat. TBD whether or not the code comment should also be included. I don't see why not.

Describe alternatives you've considered
I don't see an alternative that makes more sense than putting the description in right when it is compiled.

Additional context
None. Other than I love this project.

[near-operation-file] typesSuffix from baseTypesPath not taken into account.

Describe the bug
Given you generate a types file with typesSuffix and use that file as baseTypesPath for the near-operation-file preset. Then it doesn't add the typesSuffix to the types imported from the original types file, resulting in an error.

To Reproduce
Steps to reproduce the behavior:

Code sandbox

Notice the error on line 40 in document.generated.ts.

  1. My GraphQL schema:
type Query {
    user(id: ID!): User!
}

type User {
    id: ID!
    username: String!
    email: String!
}
  1. My GraphQL operations:
query user {
    user(id: 1) {
        id
        username
        email
    }
}
  1. My codegen.yml config file:
schema: schema.graphql
documents: document.graphql
generates:
  src/types.ts:
    plugins:
      - typescript
      - typescript-operations
    config:
      typesSuffix: DTO
  src/:
    preset: near-operation-file
    presetConfig:
      baseTypesPath: types.ts
    plugins:
      - typescript
      - typescript-operations

Expected behavior
Expected document.generated.ts to use the typesSuffix from types.ts when importing types from types.ts:

import * as Types from './src/types';
Types.UserDTO

instead of:

import * as Types from './src/types;
Types.User // Namespace '/src/types' has no exported member 'User'

Environment:

  • OS: MacOS 11.3
  • @graphql-codegen/add: 2.0.2,
  • @graphql-codegen/cli: 1.21.4,
  • @graphql-codegen/near-operation-file-preset: 1.18.0,
  • @graphql-codegen/typescript: 1.22.0,
  • @graphql-codegen/typescript-operations: 1.17.16,
  • NodeJS: 14

`Unable to find field "__type" on type "Query"` with presets `import-types` and `near-operation-file`

Describe the bug

When I have a query against Query.__type() in combination with import-types or near-operation, graphql-codegen fails:

 yarn run v1.22.0
$ yarn gql:download && yarn gql:generate
$ get-graphql-schema http://127.0.0.1:8000 > src/graphql/schema.graphql
$ yarn gql:codegen
$ graphql-codegen --config codegen.yml
  ✔ Parse configuration
  ❯ Generate outputs
    ✔ Generate src/graphql/graphql-types.tsx
    ❯ Generate to src/graphql/graphql-operations.tsx (using EXPERIMENTAL preset "
import-types")
      ✔ Load GraphQL schemas
      ✔ Load GraphQL documents
      ✖ Generate
        → Unable to find field "__type" on type "Query"!
    ✔ Generate src/graphql/fragment-introspection.ts


 Found 1 error

  ✖ src/graphql/graphql-operations.tsx
    Error: Unable to find field "__type" on type "Query"!
        at nextTypeName (/base/node_modules/@graphql-codegen/plugin-helpers/index.cjs.js:141:39)
        at Object.enter (/base/node_modules/@graphql-codegen/plugin-helpers/index.cjs.js:160:23)
        at Object.visit (/base/node_modules/graphql/language/visitor.js:242:26)
        at Object.isUsingTypes (/base/node_modules/@graphql-codegen/plugin-helpers/index.cjs.js:121:13)
        at options.documents.map.documentFile (/base/node_modules/@graphql-codegen/import-types-preset/index.cjs.js:30:31)
        at Array.map (<anonymous>)
        at Object.buildGeneratesSection (/base/node_modules/@graphql-codegen/import-types-preset/index.cjs.js:29:27)
        at Listr.task.wrapTask (/base/node_modules/@graphql-codegen/cli/bin.js:799:64)
        at process._tickCallback (internal/process/next_tick.js:68:7)
    Error: Unable to find field "__type" on type "Query"!
        at nextTypeName (/base/node_modules/@graphql-codegen/plugin-helpers/index.cjs.js:141:39)
        at Object.enter (/base/node_modules/@graphql-codegen/plugin-helpers/index.cjs.js:160:23)
        at Object.visit (/base/node_modules/graphql/language/visitor.js:242:26)
        at Object.isUsingTypes (/base/node_modules/@graphql-codegen/plugin-helpers/index.cjs.js:121:13)
        at options.documents.map.documentFile (/base/node_modules/@graphql-codegen/import-types-preset/index.cjs.js:30:31)
        at Array.map (<anonymous>)
        at Object.buildGeneratesSection (/base/node_modules/@graphql-codegen/import-types-preset/index.cjs.js:29:27)
        at Listr.task.wrapTask (/base/node_modules/@graphql-codegen/cli/bin.js:799:64)
        at process._tickCallback (internal/process/next_tick.js:68:7)


Something went wrong
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
[1]    12898 exit 1     yarn gql

To Reproduce

When I dump everything into one target file with plugins

- typescript
- typescript-operations
- typescript-react-apollo

I get no error, but once I split it up into multiple files & change the preset to either import-types or near-operation-file, I get the error message

Unable to find field "__type" on type "Query"

True, that field is not explicitly part of my Query type in the schema, but it should be there implicitly for every schema.

It seems that these implicit fields are not available from the presets?

Steps to reproduce the behavior:

Use a query like

export const GetFilterInfo = gql`
    query FilterInfo($filterName: String!) {
        __type(name: $filterName) {
            kind
            name
            description
            inputFields {
                name
                type {
                    kind
                    name
                }
            }
        }
    }
`;

with the presets import-types or near-operation-file.

Expected behavior

No error message, files get generated.

Environment:

  • OS: Linux
  • @graphql-codegen/^1.13.2:
  • NodeJS: 10.17.0

[typescript-urql-graphcache] Optimistic Update Typename Hardcoded

Describe the bug

When using the codegen cli tool to create my ts definitions for urql graphcache, the prefix for the mutation args for optimistic update functions is always "Mutation". In my schema it should be prefixed with "Mutation_Root".

The error is caused on this line
https://github.com/dotansimha/graphql-code-generator/blob/e8bc3fd2382d291aaacd4c78b54c759f4d791218/packages/plugins/typescript/urql-graphcache/src/index.ts#L189

Whereas the naming on the regular update function is correct because it dynamically creates the mutation arg prefix with rootType.name
https://github.com/dotansimha/graphql-code-generator/blob/e8bc3fd2382d291aaacd4c78b54c759f4d791218/packages/plugins/typescript/urql-graphcache/src/index.ts#L156

To Reproduce
npm run generate

  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "test:unit": "vue-cli-service test:unit",
    "test:e2e": "vue-cli-service test:e2e",
    "lint": "vue-cli-service lint",
    "generate": "graphql-codegen"
  },
  1. My GraphQL schema:
{
  "__schema": {
    "queryType": {
      "name": "query_root"
    },
    "mutationType": {
      "name": "mutation_root"
    },
    "subscriptionType": {
      "name": "subscription_root"
    },
    ...
}
  1. My GraphQL operations:

Incorrect optimistic updates

image

Correct graphcache updates

image

  1. My codegen.yml config file:
schema: 
  - ${VUE_APP_API_ROOT}:
      headers:
        Content-Type: application/json
        x-hasura-admin-secret: ${HASURA_SECRET}
documents: src/**/*.graphql
generates: 
  src/assets/generated/schema.json:
    plugins:
      - urql-introspection
  src/assets/generated/api.ts:
    config: 
      gqlImport: '@urql/vue#gql'
      dedupeOperationSuffix: true
    plugins:
      - typescript
      - typescript-urql-graphcache
      - typescript-operations
      - typescript-vue-urql

Expected behavior

Optimistic update arguments prefix should be dynamically named based on the definition in the schema.

Environment:

  • OS: Pop!_OS 21.04
  • "@graphql-codegen/cli": "^2.0.1",
  • "@graphql-codegen/typescript": "^2.0.0",
  • "@graphql-codegen/typescript-operations": "^2.0.1",-
  • "@graphql-codegen/typescript-urql-graphcache": "^2.1.1",
  • "@graphql-codegen/typescript-vue-urql": "^2.0.0",
  • NodeJS: v14.17.3

Additional context

MongoDB Plugin: Add way to specify custom type for discriminatorField

When using the MongoDB TypeScript plugin and specifying discriminatorField on an abstractEntity/union it results in a string property. It would be very useful to be able to specify an enum here to take full advantage of TypeScript.

I have two suggestions on how this could work:

  1. Add a configuration option in codegen.yml - something similar to "mappers" for Resolvers. It could look something like this:
discriminatorTypeMappers:
   MyAbstractEntity: MyFirstDiscriminatorFieldEnum
   MyAbstractUnion: MySecondDiscriminatorFieldEnum
  1. Add possibility in the discriminatorField to map it to an enum in the GraphQL schema. Probably not optimal since we'd often not want to expose this to the client, but only use it internally on the backend.

My current workaround is to extend the types generated by Codegen. I think a solution like this would make it a lot cleaner and radically improve the usability of abstractEntity/union.

Type-graphql doesn't support a scalar as input argument type

Describe the bug
When a mutation argument type contains a scalar property the generated code fails to compile. The scalar is wrapped with either a FixFixture<> or Maybe<> with the error message "Cannot find name ''"

To Reproduce

  1. Create a schema that contains a mutation with with null or non-null argument scalar property (see below)
  2. Generates the following code for the argument.

@TypeGraphQL.ArgsType()
export class MutationRemoveUserArgs {

@TypeGraphQL.Field(type => CustomID)
id!: FixDecorator;
};

Error message: "Cannot find name 'CustomID"

  1. My GraphQL schema:
scalar CustomID

interface Node {
    id: CustomID!
}

type User implements Node {
    id: CustomID!
    username: String!
    email: String!
}

type Mutation {
    removeUser(id: CustomID!): RemoveByIdEmployeePayload
}

type RemoveByIdEmployeePayload {
    id: CustomID!
}
  1. My GraphQL operations:
None
  1. My codegen.yml config file:
schema: schema.graphql
config:
    scalars:
        CustomID: String
generates:
    ./generatedTypeGraphQL.ts:
        plugins:
            - typescript-type-graphql

Expected behavior

Expecting the argument class to be:

@TypeGraphQL.ArgsType()
export class MutationRemoveUserArgs {

@TypeGraphQL.Field(type => String)
id!: FixDecorator<Scalars['CustomID']>;
};

Environment:

  • OS: Mac OS
  • @graphql-codegen/...:
    "@graphql-codegen/cli": "^1.21.3",
    "@graphql-codegen/typescript-type-graphql": "^1.18.3"
  • NodeJS:v15.3.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.