stacker.news/api/ssrApollo.js

106 lines
2.4 KiB
JavaScript

import { ApolloClient, InMemoryCache } from '@apollo/client'
import { SchemaLink } from '@apollo/client/link/schema'
import { makeExecutableSchema } from 'graphql-tools'
import { getSession } from 'next-auth/client'
import resolvers from './resolvers'
import typeDefs from './typeDefs'
import models from './models'
import slashtags from './slashtags'
import { print } from 'graphql'
import lnd from './lnd'
import search from './search'
import { ME } from '../fragments/users'
import { PRICE } from '../fragments/price'
export default async function getSSRApolloClient (req, me = null) {
const session = req && await getSession({ req })
const client = new ApolloClient({
ssrMode: true,
link: new SchemaLink({
schema: makeExecutableSchema({
typeDefs,
resolvers
}),
context: {
models,
me: session
? session.user
: me,
lnd,
search,
slashtags
}
}),
cache: new InMemoryCache()
})
await client.clearStore()
return client
}
export function getGetServerSideProps (query, variables = null, notFoundFunc, requireVar) {
return async function ({ req, query: params }) {
const { nodata, ...realParams } = params
const vars = { ...realParams, ...variables }
const client = await getSSRApolloClient(req)
const { data: { me } } = await client.query({
query: ME,
variables: { skipUpdate: true }
})
const { data: { price } } = await client.query({
query: PRICE, variables: { fiatCurrency: me?.fiatCurrency }
})
// we want to use client-side cache
if (nodata && query) {
return {
props: {
me,
price,
apollo: {
query: print(query),
variables: vars
}
}
}
}
if (requireVar && !vars[requireVar]) {
return {
notFound: true
}
}
let error = null; let data = null; let props = {}
if (query) {
({ error, data } = await client.query({
query,
variables: vars
}))
if (error || !data || (notFoundFunc && notFoundFunc(data))) {
return {
notFound: true
}
}
props = {
apollo: {
query: print(query),
variables: vars
}
}
}
return {
props: {
...props,
me,
price,
data
}
}
}
}