{"id":13700848,"url":"https://github.com/lkster/graphql-to-type","last_synced_at":"2025-05-04T19:33:28.744Z","repository":{"id":182178038,"uuid":"668032868","full_name":"lkster/graphql-to-type","owner":"lkster","description":"(almost) Fully functional GraphQL request parser written completely using TypeScript's typing system","archived":false,"fork":false,"pushed_at":"2024-01-21T00:26:14.000Z","size":83,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2024-11-01T14:06:46.394Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lkster.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-07-18T21:33:40.000Z","updated_at":"2024-06-10T14:42:44.000Z","dependencies_parsed_at":"2024-06-19T02:49:36.759Z","dependency_job_id":"8d27e41c-9540-4701-bbd3-03ca9d4a8a50","html_url":"https://github.com/lkster/graphql-to-type","commit_stats":null,"previous_names":["thafog/graphql-to-type","lkster/graphql-to-type"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lkster%2Fgraphql-to-type","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lkster%2Fgraphql-to-type/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lkster%2Fgraphql-to-type/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lkster%2Fgraphql-to-type/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lkster","download_url":"https://codeload.github.com/lkster/graphql-to-type/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224406065,"owners_count":17305718,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T20:01:03.139Z","updated_at":"2024-11-13T06:31:30.047Z","avatar_url":"https://github.com/lkster.png","language":"TypeScript","funding_links":[],"categories":["Implementations"],"sub_categories":["JavaScript/TypeScript"],"readme":"# graphql-to-type [![npm version badge](https://img.shields.io/npm/v/graphql-to-type.svg)](https://www.npmjs.com/package/graphql-to-type)\n\n(almost) Fully functional GraphQL request parser written completely using TypeScript's typing system. \nAt first, I just wanted to see if it's even possible but turned out it can be actually useful in the end.\n\nhttps://github.com/ThaFog/graphql-to-type/assets/10232371/12515523-5ddd-479e-8562-b2760cfe1a68\n\n## Support progress\n\n- Transforming operation's selection set to object type\n- Transforming operation's variables to object type\n- Extracting operation type and name\n- Fields' aliases\n- Consuming comments\n- Directives (not functional, ignored in transformer)\n\nNot yet supported:\n- Fragments and fragment spreads\n\n  Not yet implemented to be parsable. It's probably possible to have them working though if some conditions are met.\n\n\nI'm thinking also about implementing generator for `TypeMap` (more about `TypeMap` below). It could be used when schema changes only.\n\n## Instalation\n\n```\n$ npm i graphql-to-type -D\n```\n\n## How to use\n\nUsage is simple. First of all, just write GraphQL request in some variable and pass inferred type to either `GraphQlOperation` or `GraphQlResponse` type. Be sure variable / property is const as inferred type should be exact string.\n\n\u003e **Note**\n\u003e For now type consumes only one and first operation from provided string. Every other operation will be just ignored. Also as of now fragments are not yet recognizable and will cause parser error.\n\n```ts\nconst query = `\n    query {\n        company {\n            ceo\n            employees\n            infoLinks {\n                elon_twitter\n            }\n        }\n    }\n`;\n\ntype queryResponse = GraphQlResponse\u003ctypeof query, TypeMap\u003e;\n/*\n    {\n        data?: {\n            company: {\n                ceo: string;\n                employees: number;\n                infoLinks: {\n                    elon_twitter: string;\n                };\n            };\n        };\n        errors?: GraphQlError[];\n        extendsions? Record\u003cstring, any\u003e;\n    }\n*/\n```\n\nSecond thing is providing `TypeMap` object, as it's seen above. This thing should include every query, mutation, scalar and other types to properly map properties to their associated types. It's safe to write it once and store in some separate file. `TypeMap` consists of `types` property and optional `query`, `mutation` and `subscription` properties. `types` should have every GraphQL type mapped to it's TypeScript type. Every operation property should have assigned types to all existing operations.\n\nHaving SpaceX API as an example, minimal effort `TypeMap` to have query above properly mapped should look like this one:\n\n```ts\n// Based on SpaceX GraphQL schema\n\nexport interface Info {\n    ceo: string;\n    employees: number;\n    infoLinks: InfoLinks;\n}\n\nexport interface InfoLinks {\n    elon_twitter: string;\n    flickr: string;\n    twitter: string;\n    website: string;\n}\n\nexport type TypeMap = {\n    query: {\n        company: Info;\n    };\n    types: {\n        Info: Info;\n        InfoLinks: InfoLinks;\n    };\n};\n```\n\nIn case parser won't be able to find associated type, it assigns `unknown` instead.\n\nIf you just want to map selection set without response object, you can use `GraphQlOperation` type instead:\n\n```ts\nconst query = `\n    query {\n        company {\n            ceo\n            employees\n            infoLinks {\n                elon_twitter\n            }\n        }\n    }\n`;\n\ntype queryOperation = GraphQlOperation\u003ctypeof query, TypeMap\u003e;\n/*\n    {\n        company: {\n            ceo: string;\n            employees: number;\n            infoLinks: {\n                elon_twitter: string;\n            };\n        };\n    };\n    }\n*/\n```\n\n### Typing variables\n\nExtracting variables works in the same way as it is with selection set with a difference this time the type returns object with typed variables:\n\n```ts\nconst query = `\n    query ($find: CoresFind, $limit: Int, $offset: Int, $order: String, $sort: String) {\n        cores(find: $find, limit: $limit, offset: $offset, order: $order, sort: $sort) {\n            block\n            missions {\n                name\n                flight\n            }\n            original_launch\n        }\n    }\n`;\n\ntype queryVariables = GraphQlVariables\u003ctypeof query, TypeMap\u003e;\n/*\n    {\n        find: CoreFind;\n        limit: number;\n        offset: number;\n        order: string;\n        sort: string;\n    }\n*/\n```\n\nwhere `TypeMap` with minimal effort looks like this:\n\n```ts\n// Based on SpaceX GraphQL schema\n\nexport interface CoresFind {\n    asds_attempts: number;\n    asds_landings: number;\n    block: number;\n    id: string;\n    missions: string;\n    original_launch: Date;\n    reuse_count: number;\n    rtls_attempts: number;\n    rtls_landings: number;\n    status: string;\n    water_landing: boolean;\n}\n\nexport type TypeMap = {\n    types: {\n        String: string;\n        Int: number;\n        Float: number;\n        Boolean: boolean;\n        CoresFind: CoresFind;\n    };\n};\n```\n\n### Types Aliases\n\nTo simplify life, you can create alias for these types so you won't need to provide `TypeMap` everytime:\n\n```ts\nimport type { GraphQlResponse, GraphQlOperation, GraphQlVariables } from 'graphql-to-type';\nimport type { TypeMap } from './type-map';\n\nexport type GqlResponse\u003cGraphQl extends string\u003e = GraphQlResponse\u003cGraphQl, TypeMap\u003e;\nexport type GqlOperation\u003cGraphQl extends string\u003e = GraphQlOperation\u003cGraphQl, TypeMap\u003e;\nexport type GqlVariables\u003cGraphQl extends string\u003e = GraphQlVariables\u003cGraphQl, TypeMap\u003e;\n```\n\n## Available Types\n\n### GraphQlOperation\n\nExtracts selection set from operation and transforms it into record type\n\n```ts\ntype GraphQlOperation\u003cGraphQl extends string, Types extends TypeMap\u003e\n```\n\n### GraphQlVariables\n\nExtracts variables from operation and transforms them into record type\n\n```ts\ntype GraphQlVariables\u003cGraphQl extends string, Types extends TypeMap\u003e\n```\n\n### GraphQlOperationName\n\nExtracts name of the operation. Returns `undefined` if operation has no name set\n\n```ts\ntype GraphQlOperationName\u003cGraphQl extends string\u003e\n```\n\n### GraphQlOperationType\n\nExtracts type of the operation. Returns `query` if no operation type is provided based on GraphQL spec.\n\n```ts\ntype GraphQlOperationType\u003cGraphQl extends string\u003e\n```\n\n\n### GraphQlResponse\n\nExtracts selection set from operation, transforms it into record type and encloses it in graphQl-compatible response type\n\n```ts\ntype GraphQlResponse\u003cGraphQl extends string, Types extends TypeMap\u003e\n```\n\n### GraphQlError\n\nDescribes potential error returned by GraphQL\n\n```ts\nexport type GraphQlError = {\n    readonly message: string;\n    readonly locations: ReadonlyArray\u003cSourceLocation\u003e;\n    readonly path?: ReadonlyArray\u003cstring | number\u003e;\n    readonly extensions?: Readonly\u003cRecord\u003cstring, any\u003e\u003e;\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flkster%2Fgraphql-to-type","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flkster%2Fgraphql-to-type","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flkster%2Fgraphql-to-type/lists"}