simple-graphql-to-typescript

Simple Typescript interface generator from GraphQL Schemas


Keywords
graphql, typescript, ts, gql, gql-ts, graphql to typescript, graphql codegen, graphql generator, graphql generator typescript, graphql typescript generator, simple graphql to typescript, graphql code generator, graphql typescript, graphql-typescript, graphql-ts, graphql-ts-generator, graphql-to-typescript, typescript-generator
License
MIT
Install
npm install simple-graphql-to-typescript@0.10.1

Documentation

Simple-graphql-to-typescript generator

Vue logo Vue logo

npm version npm downloads npm downloads

Motive

I work a lot with GraphQL apis and typescript, and since now I was always writing by hand all my interfaces/enums and input types. I search many solutions for generating them for me (Apollo codegen, graphql-to-typescript ..etc ) but it was never the result I expected. I just wanted a single file with all my types in it, without complexity.

Installation

For global use

npm i -g simple-graphql-to-typescript
#or
yarn global add simple-graphql-to-typescript

For local use

npm i simple-graphql-to-typescript --save-dev
#or
yarn add -D simple-graphql-to-typescript

Command to call

sgts

Documentation

Option Short syntax Type Description
--endpoint <endpoint> -e string(url) Your GraphQL api endpoint
--json <path to json> -j string(path) Path to your json schema file
--output <path> -o string(path)
default ./generated.ts
Path where the file must be generated
--generateMethods -G boolean Generate all your graphQL methods fully typed (Inspired by Prisma generate)
--apolloHooks -A boolean Generate useMutation and useQuery hooks typed
--withGqlQueries - boolean Add gql query strings to the generated output
--customScalars <scalars> - {"myScalar": "MyType"} Provide your custum scalars in format {"myScalar": "MyType", ...} (JSON)
--prefix <prefix> -p string
default null
Add prefix to all your types (ex: User becomes IUser with --prefix I)
--suffix <suffix> -s string
default null
Add suffix to all your types (ex: User becomes UserModel with --suffix Model)
--header <header> -head string Additional header option to fetch your schema from endpoint schema file
--jsMode -J boolean Generate the methods in Js with declaration files instead of Ts
--download -D string
default null
Specify the path to download the GraphQL intropection schema
--generate - string
default development
Specify the path to download the GraphQL intropection schema and specify the environnement file to use

Roadmap

I don't have much free time to develop feature I don't use, but feel free to send a PR!

  • Export only Gql string
  • Removed Query and mutation name in Apollo Hooks data
  • Config file .sgtsrc.js
  • Support Subscriptions
  • Support UseLazyQuery Apollo Hook
  • Highlight new generated, modified or deleted types in terminal

Simple usage exemple

sgts -e https://json-placeholder-graphql.herokuapp.com/graphql -o generated.ts

Generated result

...
export interface Post {
  user?: User;
  userId?: number;
  id?: number;
  title?: string;
  body?: string;
}

export interface User {
  id?: number;
  name?: string;
  username?: string;
  email?: string;
  phone?: string;
  website?: string;
}

export interface Comment {
  post?: Post;
  postId?: number;
  id?: number;
  name?: string;
  email?: string;
  body?: string;
}
...

Configuration file

You can also use a .sgtsrc.js file

sgts generate <yourEnv> # default = development

Exemple

.env.testing

API_URL=http://localhost:4000/graphql

.sgtsrc.js

module.exports = {
  endpoint: process.env.API_URL,
  output: './generated.ts',
};
sgts generate testing

Sgts also load your .env before loading other environnement files

Available options

{
  endpoint?: string;
  json?: string;
  output?: string;
  headers?: string;
  prefix?: string;
  suffix?: string;
  jsMode?: boolean;
  download?: string;
  customScalars?: { [x: string]: string };
  generateMethods?: boolean;
  apolloHooks?: boolean;
  withGqlQueries?: boolean;
}

Generating methods using ApolloClient

Sgts can generate all your methods fully typed and cancellabled; You just need to pass yout apolloClient instance to the root constructor of sgts

apiProvider is generated by sgts on the same files as your models with the option --generateMethods

try it with

sgts -e https://json-placeholder-graphql.herokuapp.com/graphql -G

Generated result exemple

{
  posts(): FragmentableQueryWithOptionalArgs<Post[], postsArgs> {
    return {
      $fragment: (fragment: string | DocumentNode) => {
        const { isString, isFragment, fragmentName } = guessFragmentType(fragment);
        const query = gql`
          query posts ($userId: Int) {
            posts(userId: $userId) {
              ${isString ? fragment : '...' + fragmentName}
            }
          } ${isFragment ? fragment : ''}
          `;

        return abortableQuery(query, true);
      }
    };
  },
}

Also, Sgts will generate all pageInfo fragment for pagination

Sgts handle the PageInfo fragment generation, so you just have to pass the node fragment to the function

Exemple from generated project in production

{
  /** Get list of created training */
  getMyTrainings(): FragmentableQueryWithOptionalArgs<TrainingConnection, getMyTrainingsArgs> {
      return {
        $fragment: (fragment: string | DocumentNode) => {
          const { isString, isFragment, fragmentName } = guessFragmentType(fragment);
          const query = gql`
            query getMyTrainings ($take: Int,$skip: Int) {
              getMyTrainings(take: $take,skip: $skip) {
                pageInfo {
                  hasNextPage
                }
                edges {
                  node{
                    ${isString ? fragment : '...' + fragmentName}
                  }
                }
              }
            } ${isFragment ? fragment : ''}
          `;
          return abortableQuery(query, true);
        }
      };
    },
}
const apolloClient = new ApolloClient({
  ...
});

const sgts = apiProvider(apolloClient);


// You can either use a GraphQL fragment

const commentFragment = gql`
  fragment commentFragment on Comment {
    id
    name
    body
  }
`
// OR a simple string

const commentFragment = `
  id
  name
  body
`

const commentsQuery = sgts.comments().$fragment(commentFragment);

commentsQuery.$args({postId: 5}).$fetch().then(data => console.log(data))

// You can cancel your request any time

commentsQuery.$abort();

Generating hooks using Apollo React hooks

sgts -e https://json-placeholder-graphql.herokuapp.com/graphql -G -A
const Hello = () => {
  const { loading, error, data } = usePosts(`id title`);
  if (loading) return <p>Loading ...</p>;
  return <h1>Hello {data.posts.title}!</h1>;
};

Advanced Usage exemple

sgts --endpoint https://json-placeholder-graphql.herokuapp.com/graphql --output generated.ts --prefix I --suffix Model

Generated result

...
export interface IPostModel {
  user?: IUserModel;
  userId?: number;
  id?: number;
  title?: string;
  body?: string;
}

export interface IUserModel {
  id?: number;
  name?: string;
  username?: string;
  email?: string;
  phone?: string;
  website?: string;
}

export interface ICommentModel {
  post?: IPostModel;
  postId?: number;
  id?: number;
  name?: string;
  email?: string;
  body?: string;
}

...

Runtime usage

const { sgtsGenerate } = require('simple-graphql-to-typescript');

await sgtsGenerate({
  endpoint: 'https://json-placeholder-graphql.herokuapp.com/graphql',
  output: './types.ts',
  prefix: 'I',
  suffix: 'Model',
});

Help

sgts -h

License

MIT

Victor Garcia