Skip to content

Instantly share code, notes, and snippets.

@vasco3
Last active August 28, 2020 18:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vasco3/f84d0aef6c46f14ba40ec7478cb8c394 to your computer and use it in GitHub Desktop.
Save vasco3/f84d0aef6c46f14ba40ec7478cb8c394 to your computer and use it in GitHub Desktop.
Fauna blog post
import { RecoilRoot } from 'recoil';
import React from 'react';
import App from 'next/app';
import { SWRConfig } from 'swr';
import { GraphQLClient } from 'graphql-request';
import { print } from 'graphql/language/printer';
import '../css/tailwind.css';
import AppLayout from '../layouts/AppLayout';
import AppShell from '../components/chrome/AppShell';
class MyApp extends App {
static async getInitialProps({ req }) {
const host = req
? req?.headers['host']
: typeof window !== 'undefined'
? window.location.host
: '';
if (!host) return { org: {} };
const isLocalHost = host.includes('localhost');
const domain = isLocalHost ? 'http://' + host : 'https://' + host;
const res = await fetch(domain + '/api/org');
const json = await res.json();
return { org: json };
}
render() {
const { Component, pageProps, org = {} } = this.props;
let appType = org?.settings?.appType || '';
const layoutConfig = Component.getLayoutSwitch
? Component.getLayoutSwitch({ appType })
: {
getLayout:
Component.getLayout || ((page) => <AppLayout children={page} />),
};
const fetcher = (query, source = 'FAUNA', variablesStringified) => {
const graphQLClient = ((src) => {
switch (src) {
case 'FAUNA':
default:
return new GraphQLClient('https://graphql.fauna.com/graphql', {
headers: {
authorization: `Bearer ${org?.serverSecret}`,
'X-Schema-Preview': 'partial-update-mutation',
},
});
}
})(source);
const parsedQuery = typeof query === 'string' ? query : print(query);
try {
// Needs to be flat to avoid unnecessary rerendering since swr does shallow comparison.
const variables =
typeof variablesStringified === 'string'
? JSON.parse(variablesStringified)
: variablesStringified;
return graphQLClient.request(parsedQuery, variables);
} catch (err) {
return graphQLClient.request(parsedQuery, {});
}
};
if (Component.isPublic || layoutConfig.isPublic)
return (
<RecoilRoot>
<SWRConfig value={{ fetcher }}>
{layoutConfig.getLayout(
<Component {...pageProps} appType={appType} />,
)}
</SWRConfig>
</RecoilRoot>
);
// redirect if the subdomain is unknown
if (!org?.serverSecret && typeof window !== 'undefined') {
window.location.href = 'https://turboroof.com';
}
return (
<RecoilRoot>
<SWRConfig value={{ fetcher }}>
<AppShell fetcher={fetcher} org={org}>
{layoutConfig.getLayout(
<Component {...pageProps} appType={appType} />,
)}
</AppShell>
</SWRConfig>
</RecoilRoot>
);
}
}
export default MyApp;
type Query {
customers: [Customer!]
itemPipelines: [ItemPipeline!]
quotes: [Quote!]
settings: [Setting!]
}
type Setting {
config: String!
id: String! @unique
}
const If = ({ children, orThis, it }) => {
return it ? children : orThis;
}
// usage example
<div>
<If it={age > 18} orThis={"🥤"}> 🍺 </If>
</div>
import faunadb from 'faunadb';
import keyBy from 'lodash/keyBy';
import { getSubdomain } from '../../api-utils/url';
const q = faunadb.query;
// process.env.FAUNADB_SECRET is the server secret for RouterDB
export default async function org(req, res) {
const adminClient = new faunadb.Client({
secret: process.env.FAUNADB_SECRET,
keepAlive: false,
});
const host = req?.headers['host'];
const subdomain = getSubdomain({
host,
processSubdomain: process.env.SUBDOMAIN,
});
try {
const matches = await adminClient.query(
q.Paginate(q.Match(q.Index('orgsByNameSpace'), q.Casefold(subdomain))),
);
const [appType, serverSecret] = matches?.data[0];
const childClient = new faunadb.Client({
secret: serverSecret,
keepAlive: false,
});
const settingsList = await childClient.query(
q.Map(q.Paginate(q.Match(q.Index('settings'))), (setting) =>
q.Select(['data'], q.Get(setting)),
),
);
const settings = { ...keyBy(settingsList?.data || [], 'id'), appType };
res.json({ settings, serverSecret, subdomain });
} catch (error) {
console.error(error);
res.status(error.status || 500).json({
error: error.message,
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment