feat: graphql introspection, timestamps, custom scalar skaffolding

This commit is contained in:
Vyacheslav Matyukhin 2022-04-20 02:50:19 +04:00
parent 4397a310fe
commit 297eadc59b
No known key found for this signature in database
GPG Key ID: 3D2A774C5489F96C
11 changed files with 433 additions and 96 deletions

View File

@ -14,11 +14,19 @@ generates:
plugins: plugins:
- typescript - typescript
src/graphql/introspection.json:
plugins:
- introspection:
minify: true
src/: src/:
preset: near-operation-file preset: near-operation-file
presetConfig: presetConfig:
extension: .generated.tsx extension: .generated.tsx
baseTypesPath: graphql/types.generated.ts baseTypesPath: graphql/types.generated.ts
plugins: plugins:
- typescript-operations - typescript-operations:
strictScalars: true
scalars:
Date: number
- typed-document-node - typed-document-node

415
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -88,10 +88,12 @@
"textversionjs": "^1.1.3", "textversionjs": "^1.1.3",
"ts-node": "^10.7.0", "ts-node": "^10.7.0",
"tunnel": "^0.0.6", "tunnel": "^0.0.6",
"urql": "^2.2.0" "urql": "^2.2.0",
"urql-custom-scalars-exchange": "^0.1.5"
}, },
"devDependencies": { "devDependencies": {
"@graphql-codegen/cli": "^2.6.2", "@graphql-codegen/cli": "^2.6.2",
"@graphql-codegen/introspection": "^2.1.1",
"@graphql-codegen/near-operation-file-preset": "^2.2.9", "@graphql-codegen/near-operation-file-preset": "^2.2.9",
"@graphql-codegen/schema-ast": "^2.4.1", "@graphql-codegen/schema-ast": "^2.4.1",
"@graphql-codegen/typed-document-node": "^2.2.8", "@graphql-codegen/typed-document-node": "^2.2.8",

View File

@ -1,9 +0,0 @@
export interface DashboardItem {
id: string;
title: string;
description: string;
contents: any;
timestamp: string;
creator: string;
extra: any;
}

File diff suppressed because one or more lines are too long

View File

@ -7,7 +7,7 @@ import { AppProps } from "next/app";
import Router from "next/router"; import Router from "next/router";
import NProgress from "nprogress"; import NProgress from "nprogress";
import { graphqlEndpoint } from "../web/urql"; import { getUrqlClientOptions } from "../web/urql";
Router.events.on("routeChangeStart", (as, { shallow }) => { Router.events.on("routeChangeStart", (as, { shallow }) => {
if (!shallow) { if (!shallow) {
@ -25,9 +25,6 @@ function MyApp({ Component, pageProps }: AppProps) {
); );
} }
export default withUrqlClient( export default withUrqlClient((ssr) => getUrqlClientOptions(ssr), {
() => ({ ssr: false,
url: graphqlEndpoint, })(MyApp);
}),
{ ssr: false }
)(MyApp);

View File

@ -2,21 +2,21 @@ import * as Types from '../../graphql/types.generated';
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
import { QuestionFragmentDoc } from '../search/queries.generated'; import { QuestionFragmentDoc } from '../search/queries.generated';
export type DashboardFragment = { __typename?: 'Dashboard', id: string, title: string, description: string, creator: string, questions: Array<{ __typename?: 'Question', id: string, url: string, title: string, description: string, timestamp: any, visualization?: string | null, options: Array<{ __typename?: 'ProbabilityOption', name?: string | null, probability?: number | null }>, platform: { __typename?: 'Platform', id: string, label: string }, qualityIndicators: { __typename?: 'QualityIndicators', stars: number, numForecasts?: number | null } }> }; export type DashboardFragment = { __typename?: 'Dashboard', id: string, title: string, description: string, creator: string, questions: Array<{ __typename?: 'Question', id: string, url: string, title: string, description: string, timestamp: number, visualization?: string | null, options: Array<{ __typename?: 'ProbabilityOption', name?: string | null, probability?: number | null }>, platform: { __typename?: 'Platform', id: string, label: string }, qualityIndicators: { __typename?: 'QualityIndicators', stars: number, numForecasts?: number | null } }> };
export type DashboardByIdQueryVariables = Types.Exact<{ export type DashboardByIdQueryVariables = Types.Exact<{
id: Types.Scalars['ID']; id: Types.Scalars['ID'];
}>; }>;
export type DashboardByIdQuery = { __typename?: 'Query', result: { __typename?: 'Dashboard', id: string, title: string, description: string, creator: string, questions: Array<{ __typename?: 'Question', id: string, url: string, title: string, description: string, timestamp: any, visualization?: string | null, options: Array<{ __typename?: 'ProbabilityOption', name?: string | null, probability?: number | null }>, platform: { __typename?: 'Platform', id: string, label: string }, qualityIndicators: { __typename?: 'QualityIndicators', stars: number, numForecasts?: number | null } }> } }; export type DashboardByIdQuery = { __typename?: 'Query', result: { __typename?: 'Dashboard', id: string, title: string, description: string, creator: string, questions: Array<{ __typename?: 'Question', id: string, url: string, title: string, description: string, timestamp: number, visualization?: string | null, options: Array<{ __typename?: 'ProbabilityOption', name?: string | null, probability?: number | null }>, platform: { __typename?: 'Platform', id: string, label: string }, qualityIndicators: { __typename?: 'QualityIndicators', stars: number, numForecasts?: number | null } }> } };
export type CreateDashboardMutationVariables = Types.Exact<{ export type CreateDashboardMutationVariables = Types.Exact<{
input: Types.CreateDashboardInput; input: Types.CreateDashboardInput;
}>; }>;
export type CreateDashboardMutation = { __typename?: 'Mutation', result: { __typename?: 'CreateDashboardResult', dashboard: { __typename?: 'Dashboard', id: string, title: string, description: string, creator: string, questions: Array<{ __typename?: 'Question', id: string, url: string, title: string, description: string, timestamp: any, visualization?: string | null, options: Array<{ __typename?: 'ProbabilityOption', name?: string | null, probability?: number | null }>, platform: { __typename?: 'Platform', id: string, label: string }, qualityIndicators: { __typename?: 'QualityIndicators', stars: number, numForecasts?: number | null } }> } } }; export type CreateDashboardMutation = { __typename?: 'Mutation', result: { __typename?: 'CreateDashboardResult', dashboard: { __typename?: 'Dashboard', id: string, title: string, description: string, creator: string, questions: Array<{ __typename?: 'Question', id: string, url: string, title: string, description: string, timestamp: number, visualization?: string | null, options: Array<{ __typename?: 'ProbabilityOption', name?: string | null, probability?: number | null }>, platform: { __typename?: 'Platform', id: string, label: string }, qualityIndicators: { __typename?: 'QualityIndicators', stars: number, numForecasts?: number | null } }> } } };
export const DashboardFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Dashboard"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Dashboard"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"creator"}},{"kind":"Field","name":{"kind":"Name","value":"questions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Question"}}]}}]}},...QuestionFragmentDoc.definitions]} as unknown as DocumentNode<DashboardFragment, unknown>; export const DashboardFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Dashboard"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Dashboard"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"creator"}},{"kind":"Field","name":{"kind":"Name","value":"questions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Question"}}]}}]}},...QuestionFragmentDoc.definitions]} as unknown as DocumentNode<DashboardFragment, unknown>;
export const DashboardByIdDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"DashboardById"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"result"},"name":{"kind":"Name","value":"dashboard"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Dashboard"}}]}}]}},...DashboardFragmentDoc.definitions]} as unknown as DocumentNode<DashboardByIdQuery, DashboardByIdQueryVariables>; export const DashboardByIdDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"DashboardById"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"result"},"name":{"kind":"Name","value":"dashboard"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Dashboard"}}]}}]}},...DashboardFragmentDoc.definitions]} as unknown as DocumentNode<DashboardByIdQuery, DashboardByIdQueryVariables>;

View File

@ -105,7 +105,7 @@ const getCurrencySymbolIfNeeded = ({
const showFirstQualityIndicator = ({ const showFirstQualityIndicator = ({
numforecasts, numforecasts,
timestamp, lastUpdated,
showTimeStamp, showTimeStamp,
qualityindicators, qualityindicators,
}) => { }) => {
@ -124,7 +124,7 @@ const showFirstQualityIndicator = ({
<circle cx="4" cy="4" r="4" fill="rgb(29, 78, 216)" /> <circle cx="4" cy="4" r="4" fill="rgb(29, 78, 216)" />
</svg> </svg>
{`Last updated: ${ {`Last updated: ${
timestamp && !!timestamp.slice ? timestamp.slice(0, 10) : "unknown" lastUpdated ? lastUpdated.toISOString().slice(0, 10) : "unknown"
}`} }`}
</span> </span>
); );
@ -135,13 +135,13 @@ const showFirstQualityIndicator = ({
const displayQualityIndicators: React.FC<{ const displayQualityIndicators: React.FC<{
numforecasts: number; numforecasts: number;
timestamp: number; lastUpdated: Date;
showTimeStamp: boolean; showTimeStamp: boolean;
qualityindicators: any; qualityindicators: any;
platform: string; // id string - e.g. "goodjudgment", not "Good Judgment" platform: string; // id string - e.g. "goodjudgment", not "Good Judgment"
}> = ({ }> = ({
numforecasts, numforecasts,
timestamp, lastUpdated,
showTimeStamp, showTimeStamp,
qualityindicators, qualityindicators,
platform, platform,
@ -151,7 +151,7 @@ const displayQualityIndicators: React.FC<{
<div className="text-sm"> <div className="text-sm">
{showFirstQualityIndicator({ {showFirstQualityIndicator({
numforecasts, numforecasts,
timestamp, lastUpdated,
showTimeStamp, showTimeStamp,
qualityindicators, qualityindicators,
})} })}
@ -238,7 +238,7 @@ interface Props {
platformLabel: string; platformLabel: string;
numforecasts: any; numforecasts: any;
qualityindicators: any; qualityindicators: any;
timestamp: any; lastUpdated: Date;
showTimeStamp: boolean; showTimeStamp: boolean;
expandFooterToFullWidth: boolean; expandFooterToFullWidth: boolean;
} }
@ -249,7 +249,7 @@ export const QuestionFooter: React.FC<Props> = ({
platformLabel, platformLabel,
numforecasts, numforecasts,
qualityindicators, qualityindicators,
timestamp, lastUpdated,
showTimeStamp, showTimeStamp,
expandFooterToFullWidth, expandFooterToFullWidth,
}) => { }) => {
@ -288,7 +288,7 @@ export const QuestionFooter: React.FC<Props> = ({
> >
{displayQualityIndicators({ {displayQualityIndicators({
numforecasts, numforecasts,
timestamp, lastUpdated,
showTimeStamp, showTimeStamp,
qualityindicators, qualityindicators,
platform, platform,

View File

@ -254,13 +254,14 @@ const CopyText: React.FC<{ text: string; displayText: string }> = ({
</div> </div>
); );
const LastUpdated: React.FC<{ timestamp: string }> = ({ timestamp }) => ( const LastUpdated: React.FC<{ timestamp: Date }> = ({ timestamp }) => (
<div className="flex items-center"> <div className="flex items-center">
<svg className="mt-1" height="10" width="16"> <svg className="mt-1" height="10" width="16">
<circle cx="4" cy="4" r="4" fill="rgb(29, 78, 216)" /> <circle cx="4" cy="4" r="4" fill="rgb(29, 78, 216)" />
</svg> </svg>
<span className="text-gray-600"> <span className="text-gray-600">
Last updated: {timestamp ? timestamp.slice(0, 10) : "unknown"} Last updated:{" "}
{timestamp ? timestamp.toISOString().slice(0, 10) : "unknown"}
</span> </span>
</div> </div>
); );
@ -290,6 +291,7 @@ export const DisplayQuestion: React.FC<Props> = ({
expandFooterToFullWidth, expandFooterToFullWidth,
showIdToggle, showIdToggle,
}) => { }) => {
const lastUpdated = new Date(timestamp * 1000);
const displayTimestampAtBottom = const displayTimestampAtBottom =
checkIfDisplayTimeStampAtBottom(qualityIndicators); checkIfDisplayTimeStampAtBottom(qualityIndicators);
@ -331,7 +333,7 @@ export const DisplayQuestion: React.FC<Props> = ({
showTimeStamp && !displayTimestampAtBottom ? "sm:block" : "" showTimeStamp && !displayTimestampAtBottom ? "sm:block" : ""
}`} }`}
> >
<LastUpdated timestamp={timestamp} /> <LastUpdated timestamp={lastUpdated} />
</div> </div>
</div> </div>
)} )}
@ -343,7 +345,7 @@ export const DisplayQuestion: React.FC<Props> = ({
showTimeStamp && !displayTimestampAtBottom ? "sm:block" : "" showTimeStamp && !displayTimestampAtBottom ? "sm:block" : ""
} ml-6`} } ml-6`}
> >
<LastUpdated timestamp={timestamp} /> <LastUpdated timestamp={lastUpdated} />
</div> </div>
</div> </div>
)} )}
@ -368,7 +370,7 @@ export const DisplayQuestion: React.FC<Props> = ({
} self-center`} } self-center`}
> >
{/* This one is exclusively for mobile*/} {/* This one is exclusively for mobile*/}
<LastUpdated timestamp={timestamp} /> <LastUpdated timestamp={lastUpdated} />
</div> </div>
<div className="w-full"> <div className="w-full">
<QuestionFooter <QuestionFooter
@ -377,7 +379,7 @@ export const DisplayQuestion: React.FC<Props> = ({
platformLabel={platform.label} platformLabel={platform.label}
numforecasts={qualityIndicators.numForecasts} numforecasts={qualityIndicators.numForecasts}
qualityindicators={qualityIndicators} qualityindicators={qualityIndicators}
timestamp={timestamp} lastUpdated={lastUpdated}
showTimeStamp={showTimeStamp && displayTimestampAtBottom} showTimeStamp={showTimeStamp && displayTimestampAtBottom}
expandFooterToFullWidth={expandFooterToFullWidth} expandFooterToFullWidth={expandFooterToFullWidth}
/> />

View File

@ -1,19 +1,19 @@
import * as Types from '../../graphql/types.generated'; import * as Types from '../../graphql/types.generated';
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
export type QuestionFragment = { __typename?: 'Question', id: string, url: string, title: string, description: string, timestamp: any, visualization?: string | null, options: Array<{ __typename?: 'ProbabilityOption', name?: string | null, probability?: number | null }>, platform: { __typename?: 'Platform', id: string, label: string }, qualityIndicators: { __typename?: 'QualityIndicators', stars: number, numForecasts?: number | null } }; export type QuestionFragment = { __typename?: 'Question', id: string, url: string, title: string, description: string, timestamp: number, visualization?: string | null, options: Array<{ __typename?: 'ProbabilityOption', name?: string | null, probability?: number | null }>, platform: { __typename?: 'Platform', id: string, label: string }, qualityIndicators: { __typename?: 'QualityIndicators', stars: number, numForecasts?: number | null } };
export type FrontpageQueryVariables = Types.Exact<{ [key: string]: never; }>; export type FrontpageQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type FrontpageQuery = { __typename?: 'Query', result: Array<{ __typename?: 'Question', id: string, url: string, title: string, description: string, timestamp: any, visualization?: string | null, options: Array<{ __typename?: 'ProbabilityOption', name?: string | null, probability?: number | null }>, platform: { __typename?: 'Platform', id: string, label: string }, qualityIndicators: { __typename?: 'QualityIndicators', stars: number, numForecasts?: number | null } }> }; export type FrontpageQuery = { __typename?: 'Query', result: Array<{ __typename?: 'Question', id: string, url: string, title: string, description: string, timestamp: number, visualization?: string | null, options: Array<{ __typename?: 'ProbabilityOption', name?: string | null, probability?: number | null }>, platform: { __typename?: 'Platform', id: string, label: string }, qualityIndicators: { __typename?: 'QualityIndicators', stars: number, numForecasts?: number | null } }> };
export type SearchQueryVariables = Types.Exact<{ export type SearchQueryVariables = Types.Exact<{
input: Types.SearchInput; input: Types.SearchInput;
}>; }>;
export type SearchQuery = { __typename?: 'Query', result: Array<{ __typename?: 'Question', id: string, url: string, title: string, description: string, timestamp: any, visualization?: string | null, options: Array<{ __typename?: 'ProbabilityOption', name?: string | null, probability?: number | null }>, platform: { __typename?: 'Platform', id: string, label: string }, qualityIndicators: { __typename?: 'QualityIndicators', stars: number, numForecasts?: number | null } }> }; export type SearchQuery = { __typename?: 'Query', result: Array<{ __typename?: 'Question', id: string, url: string, title: string, description: string, timestamp: number, visualization?: string | null, options: Array<{ __typename?: 'ProbabilityOption', name?: string | null, probability?: number | null }>, platform: { __typename?: 'Platform', id: string, label: string }, qualityIndicators: { __typename?: 'QualityIndicators', stars: number, numForecasts?: number | null } }> };
export const QuestionFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Question"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Question"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"timestamp"}},{"kind":"Field","name":{"kind":"Name","value":"options"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"probability"}}]}},{"kind":"Field","name":{"kind":"Name","value":"platform"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"label"}}]}},{"kind":"Field","name":{"kind":"Name","value":"qualityIndicators"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"stars"}},{"kind":"Field","name":{"kind":"Name","value":"numForecasts"}}]}},{"kind":"Field","name":{"kind":"Name","value":"visualization"}}]}}]} as unknown as DocumentNode<QuestionFragment, unknown>; export const QuestionFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Question"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Question"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"timestamp"}},{"kind":"Field","name":{"kind":"Name","value":"options"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"probability"}}]}},{"kind":"Field","name":{"kind":"Name","value":"platform"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"label"}}]}},{"kind":"Field","name":{"kind":"Name","value":"qualityIndicators"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"stars"}},{"kind":"Field","name":{"kind":"Name","value":"numForecasts"}}]}},{"kind":"Field","name":{"kind":"Name","value":"visualization"}}]}}]} as unknown as DocumentNode<QuestionFragment, unknown>;
export const FrontpageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Frontpage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"result"},"name":{"kind":"Name","value":"frontpage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Question"}}]}}]}},...QuestionFragmentDoc.definitions]} as unknown as DocumentNode<FrontpageQuery, FrontpageQueryVariables>; export const FrontpageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Frontpage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"result"},"name":{"kind":"Name","value":"frontpage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Question"}}]}}]}},...QuestionFragmentDoc.definitions]} as unknown as DocumentNode<FrontpageQuery, FrontpageQueryVariables>;

View File

@ -1,19 +1,40 @@
import { initUrqlClient } from "next-urql"; import { initUrqlClient, SSRExchange } from "next-urql";
import { cacheExchange, dedupExchange, fetchExchange, ssrExchange } from "urql"; import { cacheExchange, dedupExchange, fetchExchange, ssrExchange } from "urql";
import customScalarsExchange from "urql-custom-scalars-exchange";
import schema from "../graphql/introspection.json";
import { getBasePath } from "./utils"; import { getBasePath } from "./utils";
export const graphqlEndpoint = `${getBasePath()}/api/graphql`; export const graphqlEndpoint = `${getBasePath()}/api/graphql`;
const scalarsExchange = customScalarsExchange({
// Types don't match for some reason.
// Related:
// - https://github.com/apollographql/apollo-tooling/issues/1491
// - https://spectrum.chat/urql/help/schema-property-kind-is-missing-in-type~29c8f416-068c-485a-adf1-935686b99d05
schema: schema as any,
scalars: {
/* not compatible with next.js serialization limitations, unfortunately */
// Date(value: number) {
// return new Date(value * 1000);
// },
},
});
export const getUrqlClientOptions = (ssr: SSRExchange) => ({
url: graphqlEndpoint,
exchanges: [
dedupExchange,
scalarsExchange,
cacheExchange,
ssr,
fetchExchange,
],
});
// for getServerSideProps/getStaticProps only // for getServerSideProps/getStaticProps only
export const ssrUrql = () => { export const ssrUrql = () => {
const ssrCache = ssrExchange({ isClient: false }); const ssrCache = ssrExchange({ isClient: false });
const client = initUrqlClient( const client = initUrqlClient(getUrqlClientOptions(ssrCache), false);
{
url: graphqlEndpoint,
exchanges: [dedupExchange, cacheExchange, ssrCache, fetchExchange],
},
false
);
return [ssrCache, client] as const; return [ssrCache, client] as const;
}; };