graphile / graphile-engine

Monorepo home of graphile-build, graphile-build-pg, graphile-utils, postgraphile-core and graphql-parse-resolve-info. Build a high-performance easily-extensible GraphQL schema by combining plugins!
https://www.graphile.org/
761 stars 129 forks source link

Error: Schema must contain unique named types but contains multiple types named "Profile". #30

Closed chadfurman closed 7 years ago

chadfurman commented 7 years ago

I appologize if this is in the wrong repo. Might be more of a graphile-build-pg ticket...

I get this error for the following Schema, which you can clearly see only contains one Profile type:

# Account types determine feature sets (i.e. feature flags)
enum AccountType {
  FREE
  BASIC
  PROFESSIONAL
  ENTERPRISE
}

# All input for the `authenticate` mutation.
input AuthenticateInput {
  # An arbitrary string value with no semantic meaning. Will be included in the
  # payload verbatim. May be used to track mutations by the client.
  clientMutationId: String
  email: String!
  password: String!
}

# The output of our `authenticate` mutation.
type AuthenticatePayload {
  # The exact same `clientMutationId` that was provided in the mutation input,
  # unchanged and unused. May be used by a client to track mutations.
  clientMutationId: String
  jwt: Jwt

  # Our root query field type. Allows us to run any query from our mutation payload.
  query: Query
}

# All input for the `createAccount` mutation.
input CreateAccountInput {
  # An arbitrary string value with no semantic meaning. Will be included in the
  # payload verbatim. May be used to track mutations by the client.
  clientMutationId: String
  firstName: String!
  lastName: String!
  email: String!
  password: String!
}

# The output of our `createAccount` mutation.
type CreateAccountPayload {
  # The exact same `clientMutationId` that was provided in the mutation input,
  # unchanged and unused. May be used by a client to track mutations.
  clientMutationId: String
  profile: Profile

  # An edge for the type. May be used by Relay 1.
  profileEdge(
    # The method to use when ordering `Profile`.
    orderBy: ProfilesOrderBy = PRIMARY_KEY_ASC
  ): ProfilesEdge

  # Our root query field type. Allows us to run any query from our mutation payload.
  query: Query
}

# All input for the `createProfile` mutation.
input CreateProfileInput {
  # An arbitrary string value with no semantic meaning. Will be included in the
  # payload verbatim. May be used to track mutations by the client.
  clientMutationId: String

  # The `Profile` to be created by this mutation.
  profile: ProfileInput!
}

# The output of our `createProfile` mutation.
type CreateProfilePayload {
  # The exact same `clientMutationId` that was provided in the mutation input,
  # unchanged and unused. May be used by a client to track mutations.
  clientMutationId: String

  # The `Profile` that was created by this mutation.
  profile: Profile

  # An edge for our `Profile`. May be used by Relay 1.
  profileEdge(
    # The method to use when ordering `Profile`.
    orderBy: ProfilesOrderBy = PRIMARY_KEY_ASC
  ): ProfilesEdge

  # Our root query field type. Allows us to run any query from our mutation payload.
  query: Query
}

# A location in a connection that can be used for resuming pagination.
scalar Cursor

# A point in time as described by the [ISO
# 8601](https://en.wikipedia.org/wiki/ISO_8601) standard. May or may not include a timezone.
scalar Datetime

# All input for the `deleteProfileById` mutation.
input DeleteProfileByIdInput {
  # An arbitrary string value with no semantic meaning. Will be included in the
  # payload verbatim. May be used to track mutations by the client.
  clientMutationId: String
  id: Uuid!
}

# All input for the `deleteProfile` mutation.
input DeleteProfileInput {
  # An arbitrary string value with no semantic meaning. Will be included in the
  # payload verbatim. May be used to track mutations by the client.
  clientMutationId: String

  # The globally unique `ID` which will identify a single `Profile` to be deleted.
  nodeId: ID!
}

# The output of our `deleteProfile` mutation.
type DeleteProfilePayload {
  # The exact same `clientMutationId` that was provided in the mutation input,
  # unchanged and unused. May be used by a client to track mutations.
  clientMutationId: String
  profile: Profile
  deletedProfileId: ID

  # Our root query field type. Allows us to run any query from our mutation payload.
  query: Query
}

# A JSON Web Token defined by [RFC 7519](https://tools.ietf.org/html/rfc7519)
# which securely represents claims between two parties.
scalar Jwt

# The root mutation type which contains root level fields which mutate data.
type Mutation {
  # The authentication method takes two paramenters -- an email address and a
  # password -- and returns a JWT if successful or otherwise returns an error
  authenticate(
    # The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields.
    input: AuthenticateInput!
  ): AuthenticatePayload

  # Registers a single user account with profile and credentials. firstName /
  # lastName are limited to 80 chars.  Password will be hashed and stored.  Email
  # will be checked against a basic regex.
  createAccount(
    # The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields.
    input: CreateAccountInput!
  ): CreateAccountPayload

  # The first and last name, space separated, of the account profile
  profileFullName(
    # The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields.
    input: ProfileFullNameInput!
  ): ProfileFullNamePayload

  # Creates a single `Profile`.
  createProfile(
    # The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields.
    input: CreateProfileInput!
  ): CreateProfilePayload

  # Updates a single `Profile` using its globally unique id and a patch.
  updateProfile(
    # The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields.
    input: UpdateProfileInput!
  ): UpdateProfilePayload

  # Updates a single `Profile` using a unique key and a patch.
  updateProfileById(
    # The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields.
    input: UpdateProfileByIdInput!
  ): UpdateProfilePayload

  # Deletes a single `Profile` using its globally unique id.
  deleteProfile(
    # The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields.
    input: DeleteProfileInput!
  ): DeleteProfilePayload

  # Deletes a single `Profile` using a unique key.
  deleteProfileById(
    # The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields.
    input: DeleteProfileByIdInput!
  ): DeleteProfilePayload
}

# An object with a globally unique `ID`.
interface Node {
  # A globally unique identifier. Can be used in various places throughout the system to identify this single value.
  nodeId: ID!
}

# Information about pagination in a connection.
type PageInfo {
  # When paginating forwards, are there more items?
  hasNextPage: Boolean!

  # When paginating backwards, are there more items?
  hasPreviousPage: Boolean!

  # When paginating backwards, the cursor to continue.
  startCursor: Cursor

  # When paginating forwards, the cursor to continue.
  endCursor: Cursor
}

# Account profiles contain display information for accounts.  Every account has
# one profile.  Profiles serve as a central reference point for accounts across datatypes.
type Profile implements Node {
  # A globally unique identifier. Can be used in various places throughout the system to identify this single value.
  nodeId: ID!
  id: Uuid!

  # The first name of the user of the account.  This will show up on the site.
  firstName: String!

  # The last name of the account holder.  This will show up on the site.
  lastName: String

  # An account's type is determined by the payment package selected for that
  # account.  Different account types are associated with different sets of feature flags.
  accountType: AccountType!
  createdAt: Datetime!
  updatedAt: Datetime!
  image: String
}

# A condition to be used against `Profile` object types. All fields are tested for equality and combined with a logical ‘and.’
input ProfileCondition {
  # Checks for equality with the object’s `id` field.
  id: Uuid

  # Checks for equality with the object’s `firstName` field.
  firstName: String

  # Checks for equality with the object’s `lastName` field.
  lastName: String

  # Checks for equality with the object’s `accountType` field.
  accountType: AccountType

  # Checks for equality with the object’s `createdAt` field.
  createdAt: Datetime

  # Checks for equality with the object’s `updatedAt` field.
  updatedAt: Datetime

  # Checks for equality with the object’s `image` field.
  image: String
}

# All input for the `profileFullName` mutation.
input ProfileFullNameInput {
  # An arbitrary string value with no semantic meaning. Will be included in the
  # payload verbatim. May be used to track mutations by the client.
  clientMutationId: String
  profile: ProfileInput
}

# The output of our `profileFullName` mutation.
type ProfileFullNamePayload {
  # The exact same `clientMutationId` that was provided in the mutation input,
  # unchanged and unused. May be used by a client to track mutations.
  clientMutationId: String
  string: String

  # Our root query field type. Allows us to run any query from our mutation payload.
  query: Query
}

# Account profiles contain display information for accounts.  Every account has
# one profile.  Profiles serve as a central reference point for accounts across datatypes.
input ProfileInput {
  id: Uuid

  # The first name of the user of the account.  This will show up on the site.
  firstName: String!

  # The last name of the account holder.  This will show up on the site.
  lastName: String

  # An account's type is determined by the payment package selected for that
  # account.  Different account types are associated with different sets of feature flags.
  accountType: AccountType
  createdAt: Datetime
  updatedAt: Datetime
  image: String
}

# Represents an update to a `Profile`. Fields that are set will be updated.
input ProfilePatch {
  id: Uuid

  # The first name of the user of the account.  This will show up on the site.
  firstName: String

  # The last name of the account holder.  This will show up on the site.
  lastName: String

  # An account's type is determined by the payment package selected for that
  # account.  Different account types are associated with different sets of feature flags.
  accountType: AccountType
  createdAt: Datetime
  updatedAt: Datetime
  image: String
}

# A connection to a list of `Profile` values.
type ProfilesConnection {
  # Information to aid in pagination.
  pageInfo: PageInfo!

  # The count of *all* `Profile` you could get from the connection.
  totalCount: Int

  # A list of edges which contains the `Profile` and cursor to aid in pagination.
  edges: [ProfilesEdge]

  # A list of `Profile` objects.
  nodes: [Profile!]
}

# A `Profile` edge in the connection.
type ProfilesEdge {
  # A cursor for use in pagination.
  cursor: Cursor

  # The `Profile` at the end of the edge.
  node: Profile!
}

# Methods to use when ordering `Profile`.
enum ProfilesOrderBy {
  PRIMARY_KEY_ASC
  PRIMARY_KEY_DESC
  NATURAL
  ID_ASC
  ID_DESC
  FIRST_NAME_ASC
  FIRST_NAME_DESC
  LAST_NAME_ASC
  LAST_NAME_DESC
  ACCOUNT_TYPE_ASC
  ACCOUNT_TYPE_DESC
  CREATED_AT_ASC
  CREATED_AT_DESC
  UPDATED_AT_ASC
  UPDATED_AT_DESC
  IMAGE_ASC
  IMAGE_DESC
}

# The root query type which gives access points into the data universe.
type Query implements Node {
  # Fetches an object given its globally unique `ID`.
  node(
    # The globally unique `ID`.
    nodeId: ID!
  ): Node
  currentProfile: Profile

  # Reads and enables paginatation through a set of `Profile`.
  allProfiles(
    # The method to use when ordering `Profile`.
    orderBy: ProfilesOrderBy = PRIMARY_KEY_ASC

    # Read all values in the set before (above) this cursor.
    before: Cursor

    # Read all values in the set after (below) this cursor.
    after: Cursor

    # Only read the first `n` values of the set.
    first: Int

    # Only read the last `n` values of the set.
    last: Int

    # Skip the first `n` values from our `after` cursor, an alternative to cursor
    # based pagination. May not be used with `last`.
    offset: Int

    # A condition to be used in determining which values should be returned by the collection.
    condition: ProfileCondition
  ): ProfilesConnection

  # Reads a single `Profile` using its globally unique `ID`.
  profile(
    # The globally unique `ID` to be used in selecting a single `Profile`.
    nodeId: ID!
  ): Profile
  profileById(id: Uuid!): Profile

  # Exposes the root query type nested one level down. This is helpful for Relay 1
  # which can only query top level fields if they are in a particular form.
  query: Query!

  # The root query type must be a `Node` to work well with Relay 1 mutations. This just resolves to `query`.
  nodeId: ID!
}

# All input for the `updateProfileById` mutation.
input UpdateProfileByIdInput {
  # An arbitrary string value with no semantic meaning. Will be included in the
  # payload verbatim. May be used to track mutations by the client.
  clientMutationId: String
  id: Uuid!

  # An object where the defined keys will be set on the `Profile` identified by our unique key.
  profilePatch: ProfilePatch!
}

# All input for the `updateProfile` mutation.
input UpdateProfileInput {
  # An arbitrary string value with no semantic meaning. Will be included in the
  # payload verbatim. May be used to track mutations by the client.
  clientMutationId: String

  # The globally unique `ID` which will identify a single `Profile` to be updated.
  nodeId: ID!

  # An object where the defined keys will be set on the `Profile` identified by our globally unique `ID`.
  profilePatch: ProfilePatch!
}

# The output of our `updateProfile` mutation.
type UpdateProfilePayload {
  # The exact same `clientMutationId` that was provided in the mutation input,
  # unchanged and unused. May be used by a client to track mutations.
  clientMutationId: String
  profile: Profile

  # Our root query field type. Allows us to run any query from our mutation payload.
  query: Query
}

# A universally unique identifier as defined by [RFC 4122](https://tools.ietf.org/html/rfc4122).
scalar Uuid
chadfurman commented 7 years ago

Not in latest version when I use schema generated by the latest version.

benjie commented 7 years ago

Let me know if it comes back.