graphql-tools icon indicating copy to clipboard operation
graphql-tools copied to clipboard

Transforming/Renaming Input Fields inside of a Non Null Input Object loses the mapping to the original schema

Open NullScope opened this issue 3 years ago • 0 comments

Issue workflow progress

Progress of the issue based on the Contributor Workflow

  • [ ] 1. The issue provides a reproduction available on Github, Stackblitz or CodeSandbox

    Make sure to fork this template and run yarn generate in the terminal.

    Please make sure the GraphQL Tools package versions under package.json matches yours.

  • [ ] 2. A failing test has been provided
  • [ ] 3. A local solution has been provided
  • [x] 4. A pull request is pending review

Describe the bug

Renaming/Transforming input fields of an non-null input object does not proxy correctly to the original GraphQL schema.

For example, if you have an non-null input object called draft with the input field customerEmail and rename it to customer_email, it will not be able to transform it back to customerEmail as it no longer can find the original mapping.

This is because Non Null objects are wrapped, and internally what they have is a property ofType, which is the original GraphQL type.

To Reproduce Steps to reproduce the behavior:

  • Original remote schema:
type Mutation {
  createMyCart(
    draft: MyCartDraft!
  ): Cart
}

input MyCartDraft {
  currency: String!
  country: String
  customerEmail: String
  locale: String
}

type Cart {
  id: String!
  customerEmail: String
}
  • Rename the input fields using RenameObjectFieldArguments in the following way:
new RenameObjectFieldArguments((typeName, fieldName, argName) => argName.replace(/[A-Z]/g, (letter, index) => (index > 0 ? `_${letter}` : letter)).toLowerCase())
  • Call the createMyCart mutation like so:
mutation MyMutation {
  createMyCart(draft: {
    currency: "USD"
    customer_email: "[email protected]"
    locale: "EN"
    country: "US"
  }) {
    id
    customer_email
  }
}
  • It will return an error like so:
{
  "errors": [
    {
      "message": "Field 'customer_email' is not defined by type 'MyCartDraft'; Did you mean customerEmail? (line 258, column 30):\n    draft: {currency: \"USD\", customer_email: \"[email protected]\", locale: \"EN\", country: \"US\"}\n                             ^",
      "path": [
        "createMyCart"
      ]
    }
  ],
  "data": {
    "createMyCart": null
  }
}

Expected behavior

The mutation should be executed succesfully with customer_email being transformed back into customerEmail to the original remote schema.

Environment:

  • OS: macOS 12.5.1
  • @graphql-tools/wrap: 9.0.4
  • NodeJS: v16.15.0

Additional context I'll be honest, it's just a single line change in TransformInputObjectFields.ts where it has to further check the type if it is a wrap type or not, so the line should be like this:

const parentTypeName = isWrappingType(parentType) && isInputObjectType(parentType.ofType) ? parentType.ofType.name : parentType.name;

I don't think a repo with a working example and failing test and local solution is needed for such a simple bug (but a painful one to find) but if you think it's needed please mention and I will try to create one

NullScope avatar Aug 26 '22 12:08 NullScope