Skip to content

Instantly share code, notes, and snippets.

@antoinelin
Last active June 16, 2020 09:00
Show Gist options
  • Save antoinelin/9a167b4ece4f6718968ed0e51216091f to your computer and use it in GitHub Desktop.
Save antoinelin/9a167b4ece4f6718968ed0e51216091f to your computer and use it in GitHub Desktop.
Use Urql with Prismic CMS
import {
createClient,
Exchange,
Operation,
dedupExchange,
fetchExchange,
} from 'urql'
import { cacheExchange } from '@urql/exchange-graphcache'
import Prismic from 'prismic-javascript'
import { pipe, mergeMap, fromPromise, map } from 'wonka'
import fetch from 'isomorphic-fetch'
import schema from './schema.json'
const cache = cacheExchange({ schema })
export const fetchOptionsExchange = (
promise: (
fetchOptions?: RequestInit | (() => RequestInit)
) => Promise<RequestInit | (() => RequestInit)>
): Exchange => ({ forward }) => ops$ => {
return pipe(
ops$,
mergeMap((operation: Operation) => {
const result = promise(operation.context.fetchOptions)
return pipe(
fromPromise(result),
map((fetchOptions: RequestInit | (() => RequestInit)) => ({
...operation,
context: {
...operation.context,
fetchOptions,
},
}))
)
}),
forward
)
}
function createUrqlClient() {
const baseUri = process.env.NEXT_PUBLIC_PRISMIC_URI
const accessToken = process.env.NEXT_PUBLIC_PRISMIC_TOKEN
if (!baseUri) {
throw new Error('[createUrqlClient]: PRISMIC_URI not found')
}
if (!accessToken) {
throw new Error('[createUrqlClient]: PRISMIC_TOKEN not found')
}
const prismicClient = Prismic.client(`${baseUri}/api/v2`, {
accessToken,
})
const fetchOptions = async (
fetchOptions?: RequestInit | (() => RequestInit)
): Promise<RequestInit | (() => RequestInit)> => {
try {
const api = await prismicClient.getApi()
return {
...fetchOptions,
headers: {
Authorization: `Token ${accessToken}`,
'Prismic-ref': api.masterRef.ref,
},
}
} catch (error) {
throw Error(error)
}
}
return createClient({
url: `${baseUri}/graphql`,
exchanges: [
dedupExchange,
cache,
fetchOptionsExchange(fetchOptions),
fetchExchange,
],
preferGetMethod: true,
fetch,
})
}
export const client = createUrqlClient()
require('dotenv').config()
import path from 'path'
import fs from 'fs'
import { getIntrospectionQuery } from 'graphql'
import { client } from './client'
const OUTPUT_FILE = path.resolve(__dirname, 'schema.json')
const LOGGER = {
error: (message: string) => {
process.stdout.write(message)
},
info: (message: string) => {
process.stdout.write(`${message}\n`)
}
}
const query = getIntrospectionQuery({ descriptions: false })
const main = async () => {
try {
const { data } = await client.query(query).toPromise()
if (data) {
const schema = JSON.stringify(data)
fs.writeFileSync(OUTPUT_FILE, schema)
} else {
LOGGER.error('No data')
}
LOGGER.error('File has been writen!')
process.exit()
} catch (error) {
LOGGER.error(error)
process.exit(1)
}
}
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment