Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
awinograd committed Mar 10, 2023
1 parent 9afd796 commit cf60691
Show file tree
Hide file tree
Showing 10 changed files with 3,036 additions and 35 deletions.
1 change: 1 addition & 0 deletions .graphqlrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
schema: 'https://rickandmortyapi.com/graphql'
14 changes: 14 additions & 0 deletions codegen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { CodegenConfig } from "@graphql-codegen/cli";

const config: CodegenConfig = {
schema: "https://rickandmortyapi.com/graphql",
documents: ["pages/**/*.tsx"],
ignoreNoDocuments: true, // for better experience with the watcher
generates: {
"./graphql/": {
preset: "client",
},
},
};

export default config;
48 changes: 48 additions & 0 deletions graphql/fragment-masking.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { ResultOf, TypedDocumentNode as DocumentNode, } from '@graphql-typed-document-node/core';


export type FragmentType<TDocumentType extends DocumentNode<any, any>> = TDocumentType extends DocumentNode<
infer TType,
any
>
? TType extends { ' $fragmentName'?: infer TKey }
? TKey extends string
? { ' $fragmentRefs'?: { [key in TKey]: TType } }
: never
: never
: never;

// return non-nullable if `fragmentType` is non-nullable
export function useFragment<TType>(
_documentNode: DocumentNode<TType, any>,
fragmentType: FragmentType<DocumentNode<TType, any>>
): TType;
// return nullable if `fragmentType` is nullable
export function useFragment<TType>(
_documentNode: DocumentNode<TType, any>,
fragmentType: FragmentType<DocumentNode<TType, any>> | null | undefined
): TType | null | undefined;
// return array of non-nullable if `fragmentType` is array of non-nullable
export function useFragment<TType>(
_documentNode: DocumentNode<TType, any>,
fragmentType: ReadonlyArray<FragmentType<DocumentNode<TType, any>>>
): ReadonlyArray<TType>;
// return array of nullable if `fragmentType` is array of nullable
export function useFragment<TType>(
_documentNode: DocumentNode<TType, any>,
fragmentType: ReadonlyArray<FragmentType<DocumentNode<TType, any>>> | null | undefined
): ReadonlyArray<TType> | null | undefined;
export function useFragment<TType>(
_documentNode: DocumentNode<TType, any>,
fragmentType: FragmentType<DocumentNode<TType, any>> | ReadonlyArray<FragmentType<DocumentNode<TType, any>>> | null | undefined
): TType | ReadonlyArray<TType> | null | undefined {
return fragmentType as any;
}


export function makeFragmentData<
F extends DocumentNode,
FT extends ResultOf<F>
>(data: FT, _fragment: F): FragmentType<F> {
return data as FragmentType<F>;
}
42 changes: 42 additions & 0 deletions graphql/gql.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* eslint-disable */
import * as types from './graphql';
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';

/**
* Map of all GraphQL operations in the project.
*
* This map has several performance disadvantages:
* 1. It is not tree-shakeable, so it will include all operations in the project.
* 2. It is not minifiable, so the string of a GraphQL query will be multiple times inside the bundle.
* 3. It does not support dead code elimination, so it will add unused operations.
*
* Therefore it is highly recommended to use the babel or swc plugin for production.
*/
const documents = {
"\n query Foo {\n episodes {\n __typename\n }\n }\n": types.FooDocument,
};

/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*
*
* @example
* ```ts
* const query = graphql(`query GetUser($id: ID!) { user(id: $id) { name } }`);
* ```
*
* The query argument is unknown!
* Please regenerate the types.
*/
export function graphql(source: string): unknown;

/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n query Foo {\n episodes {\n __typename\n }\n }\n"): (typeof documents)["\n query Foo {\n episodes {\n __typename\n }\n }\n"];

export function graphql(source: string) {
return (documents as any)[source] ?? {};
}

export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = TDocumentNode extends DocumentNode< infer TType, any> ? TType : never;
210 changes: 210 additions & 0 deletions graphql/graphql.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
/* eslint-disable */
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
export type Maybe<T> = T | null;
export type InputMaybe<T> = Maybe<T>;
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
ID: string;
String: string;
Boolean: boolean;
Int: number;
Float: number;
/** The `Upload` scalar type represents a file upload. */
Upload: any;
};

export enum CacheControlScope {
Private = 'PRIVATE',
Public = 'PUBLIC'
}

export type Character = {
__typename?: 'Character';
/** Time at which the character was created in the database. */
created?: Maybe<Scalars['String']>;
/** Episodes in which this character appeared. */
episode: Array<Maybe<Episode>>;
/** The gender of the character ('Female', 'Male', 'Genderless' or 'unknown'). */
gender?: Maybe<Scalars['String']>;
/** The id of the character. */
id?: Maybe<Scalars['ID']>;
/**
* Link to the character's image.
* All images are 300x300px and most are medium shots or portraits since they are intended to be used as avatars.
*/
image?: Maybe<Scalars['String']>;
/** The character's last known location */
location?: Maybe<Location>;
/** The name of the character. */
name?: Maybe<Scalars['String']>;
/** The character's origin location */
origin?: Maybe<Location>;
/** The species of the character. */
species?: Maybe<Scalars['String']>;
/** The status of the character ('Alive', 'Dead' or 'unknown'). */
status?: Maybe<Scalars['String']>;
/** The type or subspecies of the character. */
type?: Maybe<Scalars['String']>;
};

export type Characters = {
__typename?: 'Characters';
info?: Maybe<Info>;
results?: Maybe<Array<Maybe<Character>>>;
};

export type Episode = {
__typename?: 'Episode';
/** The air date of the episode. */
air_date?: Maybe<Scalars['String']>;
/** List of characters who have been seen in the episode. */
characters: Array<Maybe<Character>>;
/** Time at which the episode was created in the database. */
created?: Maybe<Scalars['String']>;
/** The code of the episode. */
episode?: Maybe<Scalars['String']>;
/** The id of the episode. */
id?: Maybe<Scalars['ID']>;
/** The name of the episode. */
name?: Maybe<Scalars['String']>;
};

export type Episodes = {
__typename?: 'Episodes';
info?: Maybe<Info>;
results?: Maybe<Array<Maybe<Episode>>>;
};

export type FilterCharacter = {
gender?: InputMaybe<Scalars['String']>;
name?: InputMaybe<Scalars['String']>;
species?: InputMaybe<Scalars['String']>;
status?: InputMaybe<Scalars['String']>;
type?: InputMaybe<Scalars['String']>;
};

export type FilterEpisode = {
episode?: InputMaybe<Scalars['String']>;
name?: InputMaybe<Scalars['String']>;
};

export type FilterLocation = {
dimension?: InputMaybe<Scalars['String']>;
name?: InputMaybe<Scalars['String']>;
type?: InputMaybe<Scalars['String']>;
};

export type Info = {
__typename?: 'Info';
/** The length of the response. */
count?: Maybe<Scalars['Int']>;
/** Number of the next page (if it exists) */
next?: Maybe<Scalars['Int']>;
/** The amount of pages. */
pages?: Maybe<Scalars['Int']>;
/** Number of the previous page (if it exists) */
prev?: Maybe<Scalars['Int']>;
};

export type Location = {
__typename?: 'Location';
/** Time at which the location was created in the database. */
created?: Maybe<Scalars['String']>;
/** The dimension in which the location is located. */
dimension?: Maybe<Scalars['String']>;
/** The id of the location. */
id?: Maybe<Scalars['ID']>;
/** The name of the location. */
name?: Maybe<Scalars['String']>;
/** List of characters who have been last seen in the location. */
residents: Array<Maybe<Character>>;
/** The type of the location. */
type?: Maybe<Scalars['String']>;
};

export type Locations = {
__typename?: 'Locations';
info?: Maybe<Info>;
results?: Maybe<Array<Maybe<Location>>>;
};

export type Query = {
__typename?: 'Query';
/** Get a specific character by ID */
character?: Maybe<Character>;
/** Get the list of all characters */
characters?: Maybe<Characters>;
/** Get a list of characters selected by ids */
charactersByIds?: Maybe<Array<Maybe<Character>>>;
/** Get a specific episode by ID */
episode?: Maybe<Episode>;
/** Get the list of all episodes */
episodes?: Maybe<Episodes>;
/** Get a list of episodes selected by ids */
episodesByIds?: Maybe<Array<Maybe<Episode>>>;
/** Get a specific locations by ID */
location?: Maybe<Location>;
/** Get the list of all locations */
locations?: Maybe<Locations>;
/** Get a list of locations selected by ids */
locationsByIds?: Maybe<Array<Maybe<Location>>>;
};


export type QueryCharacterArgs = {
id: Scalars['ID'];
};


export type QueryCharactersArgs = {
filter?: InputMaybe<FilterCharacter>;
page?: InputMaybe<Scalars['Int']>;
};


export type QueryCharactersByIdsArgs = {
ids: Array<Scalars['ID']>;
};


export type QueryEpisodeArgs = {
id: Scalars['ID'];
};


export type QueryEpisodesArgs = {
filter?: InputMaybe<FilterEpisode>;
page?: InputMaybe<Scalars['Int']>;
};


export type QueryEpisodesByIdsArgs = {
ids: Array<Scalars['ID']>;
};


export type QueryLocationArgs = {
id: Scalars['ID'];
};


export type QueryLocationsArgs = {
filter?: InputMaybe<FilterLocation>;
page?: InputMaybe<Scalars['Int']>;
};


export type QueryLocationsByIdsArgs = {
ids: Array<Scalars['ID']>;
};

export type FooQueryVariables = Exact<{ [key: string]: never; }>;


export type FooQuery = { __typename?: 'Query', episodes?: { __typename: 'Episodes' } | null };


export const FooDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Foo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episodes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}}]}}]}}]} as unknown as DocumentNode<FooQuery, FooQueryVariables>;
2 changes: 2 additions & 0 deletions graphql/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./fragment-masking";
export * from "./gql";
14 changes: 12 additions & 2 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
}
swcMinify: true,
experimental: {
forceSwcTransforms: true,
swcPlugins: [
[
"@graphql-codegen/client-preset-swc-plugin",
{ artifactDirectory: "./graphql", gqlTagName: "graphql" },
],
],
},
};

module.exports = nextConfig
module.exports = nextConfig;
9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,16 @@
"@types/react-dom": "18.0.11",
"eslint": "8.35.0",
"eslint-config-next": "^12.0.0",
"graphql": "^16.6.0",
"next": "^12.0.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"typescript": "4.9.5"
"typescript": "^4.9.5"
},
"devDependencies": {
"@graphql-codegen/cli": "^3.2.2",
"@graphql-codegen/client-preset": "^2.1.1",
"@graphql-codegen/client-preset-swc-plugin": "^0.1.2",
"ts-node": "^10.9.1"
}
}
Loading

0 comments on commit cf60691

Please sign in to comment.