{"id":15495064,"url":"https://github.com/chnapy/ts-gql-plugin","last_synced_at":"2025-04-22T20:27:08.953Z","repository":{"id":37988789,"uuid":"501390817","full_name":"Chnapy/ts-gql-plugin","owner":"Chnapy","description":"TypeScript Language Service Plugin for GraphQL DocumentNode typing","archived":false,"fork":false,"pushed_at":"2023-02-06T02:22:55.000Z","size":111894,"stargazers_count":8,"open_issues_count":5,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-19T12:16:24.041Z","etag":null,"topics":["codegen","graphql","language-service","typescript"],"latest_commit_sha":null,"homepage":"","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/Chnapy.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":"2022-06-08T19:50:46.000Z","updated_at":"2023-05-06T05:17:17.000Z","dependencies_parsed_at":"2023-02-16T14:01:23.064Z","dependency_job_id":null,"html_url":"https://github.com/Chnapy/ts-gql-plugin","commit_stats":{"total_commits":45,"total_committers":1,"mean_commits":45.0,"dds":0.0,"last_synced_commit":"804fd24f84bbb2055630742225e698a9bc1137e6"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Chnapy%2Fts-gql-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Chnapy%2Fts-gql-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Chnapy%2Fts-gql-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Chnapy%2Fts-gql-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Chnapy","download_url":"https://codeload.github.com/Chnapy/ts-gql-plugin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250317810,"owners_count":21410819,"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":["codegen","graphql","language-service","typescript"],"created_at":"2024-10-02T08:15:58.916Z","updated_at":"2025-04-22T20:27:08.932Z","avatar_url":"https://github.com/Chnapy.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ts-gql-plugin\n\n[![npm](https://img.shields.io/npm/v/ts-gql-plugin)](https://www.npmjs.com/package/ts-gql-plugin)\n[![license](https://img.shields.io/npm/l/ts-gql-plugin)](https://github.com/chnapy/ts-gql-plugin/blob/master/LICENSE)\n[![CI - CD](https://github.com/Chnapy/ts-gql-plugin/actions/workflows/ci.yml/badge.svg)](https://github.com/Chnapy/ts-gql-plugin/actions/workflows/ci.yml)\n\nA [TypeScript Language Service Plugin](https://github.com/Microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin) adding GraphQL DocumentNode typing.\n\n\u003cimg src=\"https://raw.githubusercontent.com/chnapy/ts-gql-plugin/master/.github/images/example.gif\" alt=\"ts-gql-plugin example\" /\u003e\n\n---\n\n- :triangular_ruler: Typed GraphQL operations\n- :x: No code generation\n- :toolbox: [CLI support](#cli)\n- :pencil: Editor support with autocomplete / quick-infos / \"go to definition\"\n- :link: Multi-projects support\n\n---\n\nUsing `gql` from `graphql-tag` gives you generic `DocumentNode` type, which does not allow you to manipulate typed requested data when used with Apollo for example. To resolve that you can use [code generators](https://www.graphql-code-generator.com/) creating typescript code with correct types, but it adds lot of generated code with risk of obsolete code and bad development comfort.\n\n`ts-gql-plugin` is meant to solve this issue, by replacing most of code generation by compiler-side typing, using [TypeScript Language Service Plugin](https://github.com/Microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin).\n\n## Get started\n\nInstall with your package manager\n\n```\nyarn add -D ts-gql-plugin\nnpm install -D ts-gql-plugin\n```\n\nThen add plugin to your `tsconfig.json`\n\n```jsonc\n{\n  \"compilerOptions\": {\n    \"plugins\": [\n      {\n        \"name\": \"ts-gql-plugin\"\n      }\n    ]\n  }\n}\n```\n\nSince this plugin uses [graphql-config](https://www.graphql-config.com/docs/user/user-introduction) you should add a config file targeting your GraphQL schema.\n\n```jsonc\n// .graphqlrc\n{\n  \"schema\": \"./schema.graphql\"\n}\n```\n\nDepending on how you want to use it:\n\n- [with your editor](#vscode)\n- [with a CLI](#cli)\n\nTo work this plugin requires a specific syntax:\n\n```ts\ngql(`...`);\n```\n\nA concrete example:\n\n```ts\nimport { gql } from 'graphql-tag';\n\n// TypedDocumentNode\u003c{ user, users }, { id }\u003e\ngql(`\n  query User1($id: ID!) {\n    user(id: $id) {\n      id\n      name\n  }\n    users {\n      id\n    }\n  }\n`);\n```\n\n\u003e You can find more examples in [example/](./example/).\n\n## Configuration\n\nConfiguration can be done at 2 levels: in `tsconfig.json` and in `graphql-config` file.\n\n### tsconfig.json\n\nCheckout config type \u0026 default values in [plugin-config.ts](./src/plugin-config.ts).\n\n\u003e Log level `'debug'` writes log files into `ts-gql-plugin-logs` directory. When running by VSCode this directory can be hard to find, checkout TSServer logs where files paths are logged.\n\u003e These logs contain updated code with hidden types generated by plugin.\n\n### graphql-config\n\nYou can add project-related configuration using extension `\"ts-gql\"`.\n\n```jsonc\n// .graphqlrc\n{\n  \"schema\": \"./schema.graphql\",\n  \"extensions\": {\n    \"ts-gql\": {\n      \"codegenConfig\": {\n        \"defaultScalarType\": \"unknown\",\n        \"scalars\": {\n          \"DateTime\": \"String\"\n        }\n      }\n    }\n  }\n}\n```\n\nCheckout config type in [extension-config.ts](./src/extension-config.ts).\n\n### Multi-projects configuration\n\nIf you should handle multiple GraphQL projects (= multiple schemas), define projects into your graphql-config file.\n\n```jsonc\n// .graphqlrc\n{\n  \"projects\": {\n    \"Catalog\": {\n      \"schema\": \"./catalog/schema.graphql\"\n    },\n    \"Channel\": {\n      \"schema\": \"./channel/schema.graphql\"\n    }\n  }\n}\n```\n\n\u003e graphql-config extensions should not be added in root level, but in each projects\n\nThen into your plugin config define project name regex, following your own constraints.\nThis regex is used to extract project name from operations.\n\n```jsonc\n{\n  \"compilerOptions\": {\n    \"plugins\": [\n      {\n        \"name\": \"ts-gql-plugin\",\n        \"projectNameRegex\": \"([A-Z][a-z]*)\"\n      }\n    ]\n  }\n}\n```\n\nFinally, create your operations following regex constraints.\n\n```ts\ngql(`\n  query CatalogProduct($id: ID!) {\n    product(id: $id) {\n      id\n      name\n    }\n  }\n`);\n\ngql(`\n  query ChannelItem($id: ID!) {\n    item(id: $id) {\n      id\n      name\n    }\n  }\n`);\n```\n\nWith this kind of configuration, each of these operations match corresponding project, so its own schema.\n\n## Use of generated types\n\nEven if this plugin allows you to avoid code generation, you may want to use generated types.\nFor this kind of use a global module is exposed. Named `TsGql`, you can access from it every generated types.\n\n```ts\ngql(`\n  query ProfileAuth {\n    ...\n  }\n`);\n\nconst authInput: TsGql.ProfileAuthInput = {\n  username,\n  password,\n};\n```\n\nTo use `TsGql` in a file without `gql` uses, you should put a `@ts-gql` tag with the project name you want to use, anywhere in your file.\nThis is the only way for `ts-gql-plugin` to know without performance impact when you want to access generated types.\n\n```ts\n// @ts-gql Profile\n\nconst authInput: TsGql.ProfileAuthInput = {\n  username,\n  password,\n};\n```\n\n### Enums\n\nSince enums persist on runtime, they cannot be exposed by `ts-gql-plugin`. To solve this issue, types are generated instead of enums.\n\n```gql\n# schema-profile.graphql\n\nenum OAuthProvider {\n  GOOGLE\n  FACEBOOK\n}\n```\n\nSo this enum can be used like that:\n\n```ts\n// @ts-gql Profile\n\nconst provider: TsGql.ProfileOAuthProvider = 'GOOGLE';\n```\n\nAlso you may want to list every possible values from a GraphQL enum, like to be used with HTML `\u003cselect\u003e` elements.\nTo handle this case `ts-gql-plugin` exposes an utility type, `UnionToArray`, which allows to create a tuple from an union with a strong constraint forcing to give every possible values.\n\n```ts\nimport { UnionToArray } from 'ts-gql-plugin';\n\nconst providerList: UnionToArray\u003cTsGql.ProfileOAuthProvider\u003e = [\n  'GOOGLE',\n  'FACEBOOK',\n];\n```\n\n## VSCode\n\nYou should [set your workspace's version of TypeScript](https://code.visualstudio.com/docs/typescript/typescript-compiling#_using-the-workspace-version-of-typescript), which will load plugins from your tsconfig.json file.\n\n```bash\n# Open VSCode command palette with Shift + Ctrl/Cmd + P\n\u003e TypeScript: Select TypeScript version...\n\n\u003e Use Workspace Version\n```\n\nAfter a config change you may have to restart TS server.\n\n```bash\n\u003e TypeScript: Restart TS server\n```\n\n### TS server logs\n\nYou can see plugin logs openning TS server log\n\n```bash\n\u003e TypeScript: Open TS server log\n```\n\nThen search for `ts-gql-plugin` occurences.\n\n\u003e To see more logs consider passing `logLevel` to `'verbose'` or `'debug'` !\n\n### GraphQL extension\n\nTo have highlighting between other features, you can use [GraphQL extension](https://marketplace.visualstudio.com/items?itemName=GraphQL.vscode-graphql) for VSCode.\n\n\u003e Since this extension does not handle multi-projects configurations you may want to use [GraphQL: Syntax Highlighting extension](https://marketplace.visualstudio.com/items?itemName=GraphQL.vscode-graphql-syntax) instead. This extension only gives syntax highlighting.\n\n## CLI\n\nBecause of [Language Service design limitations](https://github.com/microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin#whats-a-language-service-plugin) `tsc` does not load plugins. So building or type-checking your files using CLI cannot use `ts-gql-plugin`.\n\nAs a workaround you can use [`tsc-ls`](https://github.com/chnapy/tsc-ls), a compiler handling language service plugins.\n\n## Caveats \u0026 constraints\n\n- Tagged template expressions are not handled, because of [type-safety issue](https://github.com/microsoft/TypeScript/issues/33304)\n\n```ts\n// not handled, waiting for TypeScript #33304\ngql`\n  query {...}\n`;\n```\n\n- since Language Service feature is limited concerning types overriding, solution was to parse \u0026 override text source files during TS server process, which is subobtimal for performances (best solution would have been to work with AST)\n- as described upper, CLI is not handled out-of-box because of `tsc` design limitations\n\n## Benchmark\n\nYou can see performance impact using `ts-gql-plugin`: https://chnapy.github.io/ts-gql-plugin/dev/bench\n\nKeep in mind that this benchmark shows the \"worst case\": it's done using a [tsconfig](./example/tsconfig.benchmark1.json) including only a single [index.ts](./example/index.ts) file with only `gql` operations, so plugin use is overrepresented.\n\n## Changelog\n\nCheckout [releases](https://github.com/Chnapy/ts-gql-plugin/releases) to see each version changes.\n\n## Contribute\n\n### Issues\n\nPlease fill issues with reproductible steps \u0026 relevant logs (check VSCode [TS server logs](#ts-server-logs)).\n\n### Work on this project - get started\n\nThis project uses [devcontainers](https://code.visualstudio.com/docs/remote/containers) and is made to work on it.\n\nRun checkers\n\n```\nyarn c:type\nyarn c:lint\nyarn c:test\n```\n\nBuild\n\n```\nyarn build\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchnapy%2Fts-gql-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchnapy%2Fts-gql-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchnapy%2Fts-gql-plugin/lists"}