Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

graphql-tag-pluck inline fragment support #5140

Closed
Tracked by #5201 ...
louy opened this issue Mar 31, 2023 · 5 comments
Closed
Tracked by #5201 ...

graphql-tag-pluck inline fragment support #5140

louy opened this issue Mar 31, 2023 · 5 comments

Comments

@louy
Copy link

louy commented Mar 31, 2023

Is your feature request related to a problem? Please describe.
I'm trying to create a graphql-codegen plugin that supports the use of fragments inline with what graphql-tag supports.

The idea is: You can declare a fragment, and embed it in a tagged template literal, and that fragment will be inlined.

# Using rickandmortyapi as an example

# File 1
export const CharacterFragment = gql`
  fragment CharacterFragment on Character {
    id name created
  }
`

# File 2
const query = gql`
  ${CharacterFragment}
  query CharacterListQuery($characterId: ID!) {
    character(id: $characterId) {
      name
      ...CharacterFragment
    }
  }
`

The problem: currently graphql-tag-pluck will ignore the embedded fragment in file 2, resulting in the following 2 documents (notice empty line in doc 2):

[`
  fragment CharacterFragment on Character {
    id name created
  }
`,`

  query CharacterListQuery($characterId: ID!) {
    character(id: $characterId) {
      name
      ...CharacterFragment
    }
  }
`]

The expectation: graphql-tag-pluck should expose the different chunks that make up document 2, and ideally embed the value of ${CharacterFragment} in the exported document

# Expected documents
[`
  fragment CharacterFragment on Character {
    id name created
  }
`,
[`
`, `
  fragment CharacterFragment on Character {
    id name created
  }
`, `
  query CharacterListQuery($characterId: ID!) {
    character(id: $characterId) {
      name
      ...CharacterFragment
    }
  }
`]
]

Reason: Without knowing where the different breakpoints are in the template string literal, it's impossible (or just really difficult) to generate a static tag function signature.

See this example (line 37-41) of the currently generated types by graphql-codegen.

To generate a static type of a tagged template string, we need to know the exact value of the first argument (strings), thus we need the body value of each source as a list of strings.

Describe the solution you'd like
Possibly an addition property on Source, called strings, that only exists if the source was a template literal

Ideally (but I don't know whether this is feasible) the values (as AST nodes) as well

Describe alternatives you've considered

An interpolated string containing the resolved values of fragments stitched into the graphql document source

Additional context

N/A

@frandiox
Copy link
Contributor

frandiox commented Apr 3, 2023

If I didn't understand it wrong, I think this is related to what I'm trying to accomplish in #5127

With the pluckStringFromFile hook proposed there, I'm able to annotate the template literals with the fragments they inject, and then resolve these annotations back to full strings in a custom plugin. There are links to this custom plugin implementation in that issue, check it out if you're interested.

@louy
Copy link
Author

louy commented Apr 3, 2023

Yes that would be a great solution!

@ardatan
Copy link
Owner

ardatan commented Apr 19, 2023

GraphQL Tag Pluck is never intended to handle string interpolation. It doesn't do any execution, it only parses the AST of the code to extract GraphQL documents. The behavior is correct.
I cannot access the link you shared, but the behavior seems correct in graphql-tag-pluck. If fragments are handled in a wrong way, this is an issue on GraphQL Codegen.

@ardatan ardatan closed this as completed Apr 19, 2023
@louy
Copy link
Author

louy commented Apr 19, 2023

Thanks for looking I'll fix the link!

I wouldn't expect this package to do any interpolation, but is it at least possible to expose the AST or a small part of it to make the use case above possible?

Otherwise you're either pushing people away from using composable fragments/queries, or using this package with such use case (which is supported by graphql-tag which this is built to integrate with)

@ardatan
Copy link
Owner

ardatan commented Apr 19, 2023

graphql-tag is a runtime package that can handle interpolation during execution/runtime. This package only knows AST of the JS/TS code.
You can still visit over GraphQL AST to get used fragments then combine with other fetched fragment ASTs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants