Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/GraphtonLib/Graphton
The TypeScript SDK code generator for any (external) GraphQL API.
https://github.com/GraphtonLib/Graphton
graphql typescript
Last synced: 3 months ago
JSON representation
The TypeScript SDK code generator for any (external) GraphQL API.
- Host: GitHub
- URL: https://github.com/GraphtonLib/Graphton
- Owner: GraphtonLib
- License: mit
- Created: 2021-12-01T15:15:06.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2024-06-03T05:49:03.000Z (5 months ago)
- Last Synced: 2024-06-03T23:46:26.962Z (5 months ago)
- Topics: graphql, typescript
- Language: TypeScript
- Homepage:
- Size: 96.6 MB
- Stars: 14
- Watchers: 1
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Funding: FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
![Graphton Logo](./.github/Branding/logo-text.png)
![Current package version](https://img.shields.io/github/package-json/v/GraphtonLib/Graphton?label=Current%20Version&style=flat-square)
![Downloads on NPM](https://img.shields.io/npm/dt/@graphtonlib/graphton?style=flat-square&label=Downloads)
![GitHub Release Date](https://img.shields.io/github/release-date/GraphtonLib/Graphton?label=Release%20Date&style=flat-square)
![GitHub last commit](https://img.shields.io/github/last-commit/GraphtonLib/Graphton?style=flat-square)# Graphton
A JS/TS generator that builds a GraphQL query builder for your API
## Index
- [Installing](#installing)
- [Yarn](#yarn)
- [npm](#npm)
- [CLI Usage & options](#cli-usage--options)
- [Example CLI usage](#example-cli-usage)
- [Tip: add to scripts](#tip-add-to-scripts)
- [Using the generated file](#using-the-generated-file)
- [Build a query](#build-a-query)
- [Add returnfields](#add-returnfields)
- [Execute the query](#execute-the-query)
- [Running a mutation](#running-a-mutation)
- [Dynamically changing return fields](#dynamically-changing-return-fields)
- [Global Settings](#global-settings)
- [Reference](#reference)
- [Note: abstraction](#note-abstraction)
- [GraphtonBaseQuery](#graphtonbasequery)
- [setArgs](#setargs)
- [select](#select)
- [deselect](#deselect)
- [toQuery](#toquery)
- [get](#get)
- [do](#do)
- [GraphtonEnum](#graphtonenum)
- [parse](#parse)
- [list](#list)
- [GraphtonSettings](#graphtonsettings)
- [headers](#headers)
- [graphqlEndpoint](#graphqlendpoint)
- [Links](#links)
- [Credits](#credits)
- [Contributing](#contributing)## Installing
You can install Graphton to your dev-dependencies using a package manager.
#### Yarn
```bash
yarn add -D @graphtonlib/grapton
# Then to run:
yarn graphton generate https://example.com/graphql
```#### npm
```bash
npm i --save-dev @graphtonlib/grapton
# Then to run:
npm run graphton generate https://example.com/graphql
```## CLI Usage & options
```text
Usage: graphton generate [options]Arguments:
schemaUri URL to GraphQL endpoint or path to introspection json.Options:
-o, --outputFile Path to the generated js/ts file (default: "./src/graphton.generated.ts")
-q, --exportQueryFactoryAs How you want to import your query factory. (default: "Query")
-m, --exportMutationFactoryAs How you want to import your mutation factory. (default: "Mutation")
-s, --exportSubscriptionFactoryAs [name] If you want a subscription factory, if no name provided "Subscription" will be used. (default: false)
-Q, --queryFunction The name of the function that posts the query. (default: "get")
-M, --mutateFunction The name of the function that posts the mutation. (default: "do")
-S, --subscribeFunction The name of the function that posts the subscription. (default: "subscribe")
-d, --defineScalar Define custom scalars and their TS type. Use this if you don't want (some) scalars to be typed as string by default. (eg. --defineScalar Date=number Time=any)
-h, --help display help for command
```### Example CLI usage
```bash
yarn graphton generate -o ./src/lib/graphton.js https://example.com/graphql
```### Tip: add to scripts
As you are creating a complete custom command to generate your SDK, it might become cumbersome to remember all the options you added to the command. It's a good idea to add it to your scripts object in your `package.json` so you and your team always use the same generator command.
```json
//package.json
{
"scripts": {
"generate": "graphton generate -o ./src/lib/graphton.js https://example.com/graphql"
}
}
```Then generate the files using:
```bash
yarn generate
# Or
npm run generate
```## Using the generated file
When the ts/js file is generated you can import the `Query` and `Mutation` factory instances from it.
```typescript
import { Query, Mutation } from "./graphton.generated.js";
```> Note: the names `Query` and `Mutation` are configurable! See [CLI Usage & options](#CLI+Usage+&+options)
> Note: Since graphton does not handle subscriptions (yet?) since implementations can differ per-situation, subscription queries are optional. See [CLI Usage & options](#CLI+Usage+&+options) to how to generate them. You can use `getQuery` to output the query and use your own implementation.
> For the following examples, the example graphql schema from [example/schema.graphql](example/schema.graphql) will be used.
### Build a query
Starting a new query is fairly simple. Import `Query` from the generated file and call the method with the same name as the query you want to execute.
```typescript
import { Query } from "./example/graphton.generated.js";const usersQuery = Query.users();
const getFirstUserQuery = Query.user({ id: 1 });
```### Add returnfields
In GraphQL you have to define which fields you want to get in return. You define which ones by using `select`
```typescript
import { Query } from "./example/graphton.generated.js";const usersQuery = Query.users().returnFields((r) => r.all());
const getFirstUserQuery = Query.user({ id: 1 }).select({
id: {},
name: {},
posts: {
text: {},
},
});
```### Execute the query
After building the query, you can directly execute it with the `get()` method.
```typescript
import { Query } from "./example/graphton.generated.js";const firstUser = await Query.user({ id: 1 })
.select({
id: {},
name: {},
posts: {
text: {},
},
})
.get();// firstUser = {
// data: {
// id: 1,
// name: 'User One',
// posts: [
// {
// text: 'A sample post!'
// },
// {
// text: 'Enother sample post'
// }
// ]
// },
// axiosResponse: /*AxiosReponse*/,
// }
```### Running a mutation
Running mutations is about the same as running a query. The only diferences are:
- You import `Mutation` instead of `Query`.
- Instead of `.get()` you run `.do()````typescript
import { Mutation } from "./example/graphton.generated.js";const newUser = await Mutation.createUser({ name: "User Infinite" })
.select({ _all: {} }) // _all will expand automatically to return all shallow fields
.do();
const updatedUser = await Mutation.updateUser({ id: 1, name: "User NotOne", age: 12 })
.select({ _all: {} }) // Selecting all shallow fields again
.deselect({ name: {} }) // But removing name
.do();
```### Dynamically changing return fields
Return fields can be dynamically changed.
```typescript
import { Query } from "./example/graphton.generated.js";const firstUserQuery = Query.user({ id: 1 }).select({
id: {},
name: {}
});if (getUserPosts) {
// Adds text of all posts to the query - does NOT replace the already selected id and name
firstUserQuery.select({
posts: {
text: {},
},
});
}
```### Global Settings
You can change some of the settings, used for making the call to the server, like URL or headers.
```typescript
import { GraphtonSettings } from "./example/graphton.generated.js";GraphtonSettings.headers = { Authentication: "Bearer XXX" };
```## Reference
### Note: abstraction
Most of the reference underneath here is **very abstract**, since we do not know how the external GraphQL schema looks like which you are going to use this on. Because of this, whenever you see a `$` next to something in this guide means that **it's a value or type that is replaced to accomodate your GraphQL schema**.
That said, if you use the .ts variant of the generated output, tsc or your IDE can tell you exactly where something goes wrong.
**This is why we recommend TypeScript**. The JavaScrips variant works just fine, but without any error correction or autocomplete it might be a little harder to do the thing you want to do.
### GraphtonBaseQuery
_GraphtonBaseQuery_ is abstract, the classes you will call are generated and extended from this base class.
#### setArgs
_Only available if the query has arguments_
Signature: `setArgs(queryArgs: $ArgumentType): this`
Set the arguments for this query to `queryArgs` (overwriting previous arguments).
#### select
_Only available if the return type is an OBJECT_
`select(fields: Partial<$FieldSelectorType>): this`
Add new fields to the return object (merges recursively).
#### deselect
_Only available if the return type is an OBJECT_
Signature: `deselect(fields: Partial<$FieldSelectorType>): this`
Removes selected fields from the query.
> Note: _all will also remove objects instead of just the shallow fields.
#### toQuery
Signature: `toQuery(): string`
Transform to graphql Query string.
#### get
_Only available on Query type requests_
Signature: `get(requestConfig: AxiosRequestConfig = {}): Promise`
Execute the query and get the results.
#### do
_Only available on Mutation type requests_
Signature: `do(requestConfig: AxiosRequestConfig = {}): Promise`
Do the mutation on the server.
### GraphtonEnum
Intermediary class used to correctly parse Enums in arguments. Your Enum values can be gotten with how you would normally call an enum.
```typescript
Query.usersOrdered({
orderBy: [
{
column: UserSortColumn.age,
order: SortOrder.ASC,
},
],
});
```#### parse
> public static parse(value: keyof typeof $GraphtonEnum.possibleValues): $GraphtonEnum
Transforms a string into an enum.
Alias:
```typescript
$GraphtonEnum.VALUE;
// Is the same as
$GraphtonEnum.parse("VALUE");
```#### list
> public static list(): $GraphtonEnum[]
Gives you a list of possible enums
### GraphtonSettings
Graphton uses the static properties of this class, so you can customize these.
#### headers
> public static headers = { };
Set the headers for each following request to the server.
```typescript
GraphtonSettings.headers = { Authorization: "Bearer 123abc" };
```#### graphqlEndpoint
> public static graphqlEndpoint: string = '';
Set the URL to the GraphQL endpoint, defaults to the URL used when generating the file.
```typescript
GraphtonSettings.graphqlEndpoint = "https://mycoolexample.app/graphql";
```## Links
- [💡 GitHub Issues](https://github.com/Roboroads/laravel-tinker/issues): feature requests and bug reports
- [🙏🏼 Patreon](https://www.patreon.com/roboroads): Consider supporting this project if it helped you 😊## Credits
- [Robbin "Roboroads" Schepers](https://github.com/Roboroads) - Creator / First contributor.
- Other github projects:
- [laravel/laravel](https://github.com/laravel/laravel) - This plugin is inspired by the way Laravel Eloquent builds queries.
- [Contributors to this project](https://github.com/Roboroads/laravel-tinker/graphs/contributors)
- _I **will** name you seperately if your amount of contributions is exceptional_## Contributing
Any tips or feedback is welcome in the [Issues Tab](https://github.com/Roboroads/laravel-tinker/issues) - or better, make me a PR!
Want to be part of Graphton? Every positive contribution is welcome!