/Typescript-GraphQL-AST-parser

Bagged GraphQL AST parser written just by Typescript generics

Primary LanguageTypeScript

Typescript GraphQL AST Parser

!!! DON'T USE THIS CODE IN THE PRODUCTION !!!

If you want to interactive play with this source code, just open index.ts and set typescript version to the newest one.

This repository is just my fun project where I demonstrate power of typescript by writing Graphql parser in pure Type system.

Preview

you can interactive play with the TS-GQL parser there

Parser preview

Parser preview

Parser preview

Parser preview

Parser preview

TS Parser supports

  • Comments
    • Single line comments ✅
  • Types ✅
  • Enums ✅
  • Input Types ✅
  • Fields ✅
    • Basic Values ✅
      • String ✅
      • Boolean ✅
      • Float ✅
      • Int ✅
    • Nullable Fields ✅
    • Array Fields ✅
    • Arguments ✅
      • Default Parameters ✅
      • Fields ✅ - Basic Values ✅
        • String ✅
        • Boolean ✅
        • Float ✅
        • Int ✅
        • Nullable Fields ✅
        • Array Fields ✅
  • Interfaces
    • definition ✅
    • implements keyword ✅
  • Mutations ✅
  • Directives ✅
    • option A | B | C values: ❌
  • Scalars ✅
  • Descriptions ❌

(Btw Source code is full of bugs and edge case issues...)

Example of parser usage

This is example of using GQL TS parser

Let's have this graphQL Schema

scalar    Date1
interface Node {id: ID!}
# input CommentedPaginationPOC { input: Int! }
input Pagination { value: String }
enum OrderByKeyword {
  ASC
  DESC
}
directive @upper on FIELD_DEFINITION!
type Mutation {
  contactForm(
    input: OrderByKeyword!,
  ): String
}
type Query implements Node & Node2 {
  age: Int
  title(offset: Int!, thirdArg: String!): String!
  author: Float!
}

just by calling

type ParsedGraphQL = GetGqlAST<YOUR_GRAPHQL_SCHEMA_STRING>

GetGqlAST<T> generic will infer type with this shape:

{
  interfaces = {
    Node: {
        id: "ID";
    };
  };
  enums: {
    OrderByKeyword: "ASC" | "DESC";
  };
  inputs: {
    Pagination: {
      value: {
        value: string | null;
      };
    };
  };
  types: {
    Mutation: {
      implements: [];
      fields: {
        contactForm: {
          args: {
            input: {
              value: "OrderByKeyword";
              defaultValue: void;
            };
          };
          value: string | null;
        };
      };
    };
    Query: {
      implements: ["Node", "Node2"];
      fields: {
        title: {
            args: {
                limit: {
                    value: number | null;
                    defaultValue: "10";
                };
                offset: {
                    value: number;
                    defaultValue: null;
                };
                thirdArg: {
                    value: string;
                    defaultValue: null;
                };
            };
            value: string;
        };
        author: {
            args: {};
            value: number;
        };
        age: {
            args: {};
            value: number | null;
        }
      }
    }
  },
  scalars: {
    Date1: any;
  },
  Directives: {
    upper: "FIELD_DEFINITION";
  }
}

Parser preview

My TODOs:

Max recursion stack calling

Now there is no possible to have more then +- 21 lines, 21 types, 21 inputs, 21 enums etc... its because TS recursion deep level

So I have to resolve how to bypass recursion deep level. It could be possible by extract splitting arrays into more smaller chunks called in more recursion stacks and then joined by some heuristic rule.