JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 38
  • Score
    100M100P100Q88954F
  • License MIT

A GraphQL code generator plug-in that automatically generates utility functions for SWR.

Package Exports

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (graphql-codegen-plugin-swr) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    graphql-codegen-plugin-swr

    Forked from graphql-codegen-plugin-typescript-swr

    A GraphQL code generator plug-in that automatically generates utility functions for SWR.

    Table of Contents

    API Reference

    excludeQueries

    type: string | string[] default: ""

    Exclude queries that are matched by micromatch (case-sensitive).

    useSWRInfinite

    type: string | string[] default: ""

    Add useSWRInfinite() wrapper for the queries that are matched by micromatch (case-sensitive).

    autogenSWRKey

    type: boolean default: false

    Generate key to use useSWR() automatically.
    But, ​the cache may not work unless you separate the variables object into an external file and use it, or use a primitive type for the value of each field.

    Config Example

    generates:
      path/to/graphql.ts:
        schema: 'schemas/github.graphql'
        documents: 'src/services/github/**/*.graphql'
        plugins:
          - typescript
          - typescript-operations
          # Put `plugin-typescript-swr` below `typescript-graphql-request`
          - typescript-graphql-request
          - plugin-typescript-swr
    config:
      rawRequest: false
      excludeQueries:
        - foo*
        - bar
      useSWRInfinite:
        - hoge
        - bar{1,3}
      autogenSWRKey: true

    Usage Examples

    For the given input:

    query continents {
      continents {
        name
        countries {
          ...CountryFields
        }
      }
    }
    
    fragment CountryFields on Country {
      name
      currency
    }

    It generates SDK you can import and wrap your GraphQLClient instance, and get fully-typed SDK based on your operations:

    import { GraphQLClient } from 'graphql-request'
    import { getSdkWithHooks } from './sdk'
    
    function Continents() {
      const client = new GraphQLClient('https://countries.trevorblades.com/')
      const sdk = getSdkWithHooks(client)
    
      const { data, error } = sdk.useContinents('Continents')
    
      if (error) return <div>failed to load</div>
      if (!data) return <div>loading...</div>
    
      return (
        <ul>
          {data.continents.map((continent) => (
            <li>{continent.name}</li>
          ))}
        </ul>
      )
    }

    Pagination

    codegen.yaml

    config:
      useSWRInfinite:
        - MyQuery

    Functional Component

    const { data, size, setSize } = sdk.useMyQueryInfinite(
      'id_for_caching',
      (pageIndex, previousPageData) => {
        if (previousPageData && !previousPageData.search.pageInfo.hasNextPage)
          return null
        return [
          'after',
          previousPageData ? previousPageData.search.pageInfo.endCursor : null,
        ]
      },
      variables, // GraphQL Query Variables
      config // Configuration of useSWRInfinite
    )

    Authorization

    import { GraphQLClient } from 'graphql-request'
    import { getSdkWithHooks } from './sdk'
    import { getJwt } from './jwt'
    
    const getAuthorizedSdk = () => {
      const headers: Record<string, string> = { 'Content-Type': 'application/json' }
      const jwt = getJwt()
      if (jwt) {
        headers.Authorization = `Bearer ${jwt}`
      }
      return getSdkWithHooks(
        new GraphQLClient(`${process.env.NEXT_PUBLIC_API_URL}`, {
          headers,
        })
      )
    }
    
    export default getAuthorizedSdk

    Next.js

    // pages/posts/[slug].tsx
    import { GetStaticProps, NextPage } from 'next'
    import ErrorPage from 'next/error'
    import { useRouter } from 'next/router'
    import Article from '../components/Article'
    import sdk from '../sdk'
    import { GetArticleQuery } from '../graphql'
    
    type StaticParams = { slug: string }
    type StaticProps = StaticParams & {
      initialData: {
        articleBySlug: NonNullable<GetArticleQuery['articleBySlug']>
      }
    }
    type ArticlePageProps = StaticProps & { preview?: boolean }
    
    export const getStaticProps: GetStaticProps<StaticProps, StaticParams> = async ({
      params,
      preview = false,
      previewData
    }) => {
      if (!params) {
        throw new Error('Parameter is invalid!')
      }
    
      const { articleBySlug: article } = await sdk().GetArticle({
        slug: params.slug,
      })
    
      if (!article) {
        throw new Error('Article is not found!')
      }
    
      const props: ArticlePageProps = {
        slug: params.slug,
        preview,
        initialData: {
          articleBySlug: article
        }
      }
    
      return {
        props: preview
          ? {
              ...props,
              ...previewData,
            }
          : props,
      }
    })
    
    export const ArticlePage: NextPage<ArticlePageProps> = ({ slug, initialData, preview }) => {
      const router = useRouter()
      const { data: { article }, mutate: mutateArticle } = sdk().useGetArticle(
        `GetArticle/${slug}`, { slug }, { initialData }
      )
    
      if (!router.isFallback && !article) {
        return <ErrorPage statusCode={404} />
      }
    
      // because of typescript problem
      if (!article) {
        throw new Error('Article is not found!')
      }
    
      return (
        <Layout preview={preview}>
          <>
            <Head>
              <title>{article.title}</title>
            </Head>
            <Article article={article} />
          </>
        </Layout>
      )
    }