
Security News
MCP Community Begins Work on Official MCP Metaregistry
The MCP community is launching an official registry to standardize AI tool discovery and let agents dynamically find and install MCP servers.
awesome-graphql-client
Advanced tools
GraphQL Client with file upload support for NodeJS and browser
npm install awesome-graphql-client
import { AwesomeGraphQLClient } from 'awesome-graphql-client'
const client = new AwesomeGraphQLClient({ endpoint: '/graphql' })
// Also query can be an output from graphql-tag (see examples below)
const GetUsers = `
query getUsers {
users {
id
}
}
`
const UploadUserAvatar = `
mutation uploadUserAvatar($userId: Int!, $file: Upload!) {
updateUser(id: $userId, input: { avatar: $file }) {
id
}
}
`
client
.request(GetUsers)
.then(data =>
client.request(UploadUserAvatar, {
id: data.users[0].id,
file: document.querySelector('input#avatar').files[0],
}),
)
.then(data => console.log(data.updateUser.id))
.catch(error => console.log(error))
const { openAsBlob } = require('node:fs')
const { AwesomeGraphQLClient } = require('awesome-graphql-client')
const client = new AwesomeGraphQLClient({
endpoint: 'http://localhost:8080/graphql',
})
// Also query can be an output from graphql-tag (see examples below)
const UploadUserAvatar = `
mutation uploadUserAvatar($userId: Int!, $file: Upload!) {
updateUser(id: $userId, input: { avatar: $file }) {
id
}
}
`
const blob = await openAsBlob('./avatar.png')
client
.request(UploadUserAvatar, { file: new File([blob], 'avatar.png'), userId: 10 })
.then(data => console.log(data.updateUser.id))
.catch(error => console.log(error))
const { createReadStream, statSync } = require('node:fs')
const path = require('node:path')
const { Readable } = require('node:stream')
const { AwesomeGraphQLClient } = require('awesome-graphql-client')
class StreamableFile extends Blob {
constructor(filePath) {
const { mtime, size } = statSync(filePath)
super([])
this.name = path.parse(filePath).base
this.lastModified = mtime.getTime()
this.#filePath = filePath
Object.defineProperty(this, 'size', {
value: size,
writable: false,
})
Object.defineProperty(this, Symbol.toStringTag, {
value: 'File',
writable: false,
})
}
stream() {
return Readable.toWeb(createReadStream(this.#filePath))
}
}
const client = new AwesomeGraphQLClient({
endpoint: 'http://localhost:8080/graphql',
})
// Also query can be an output from graphql-tag (see examples below)
const UploadUserAvatar = `
mutation uploadUserAvatar($userId: Int!, $file: Upload!) {
updateUser(id: $userId, input: { avatar: $file }) {
id
}
}
`
client
.request(UploadUserAvatar, { file: new StreamableFile('./avatar.png'), userId: 10 })
.then(data => console.log(data.updateUser.id))
.catch(error => console.log(error))
AwesomeGraphQLClient
Usage:
import { AwesomeGraphQLClient } from 'awesome-graphql-client'
const client = new AwesomeGraphQLClient(config)
config
propertiesendpoint
: string - The URL to your GraphQL endpoint (required)fetch
: Function - Fetch polyfillfetchOptions
: object - Overrides for fetch optionsFormData
: object - FormData polyfillformatQuery
: function(query: any): string - Custom query formatter (see example)onError
: function(error: GraphQLRequestError | Error): void - Provided callback will be called before throwing an error (see example)isFileUpload
: function(value: unknown): boolean - Custom predicate function for checking if value is a file (see example)client
methodsclient.setFetchOptions(fetchOptions: FetchOptions)
: Sets fetch options. See examples belowclient.getFetchOptions()
: Returns current fetch optionsclient.setEndpoint(): string
: Sets a new GraphQL endpointclient.getEndpoint(): string
: Returns current GraphQL endpointclient.request(query, variables?, fetchOptions?): Promise<data>
: Sends GraphQL Request and returns data or throws an errorclient.requestSafe(query, variables?, fetchOptions?): Promise<{ ok: true, data, response } | { ok: false, error, partialData }>
: Sends GraphQL Request and returns object with 'ok: true', 'data' and 'response' or with 'ok: false', 'error' and 'partialData' fields. See examples below. Notice: this function never throws.GraphQLRequestError
instance
fieldsmessage
: string - Error messagequery
: string - GraphQL queryvariables
: string | undefined - GraphQL variablesresponse
: Response - response returned from fetchfieldErrors
: GraphQLFieldError[] - GraphQL field errorsinterface getUser {
user: { id: number; login: string } | null
}
interface getUserVariables {
id: number
}
const query = `
query getUser($id: Int!) {
user {
id
login
}
}
`
const client = new AwesomeGraphQLClient({
endpoint: 'http://localhost:3000/graphql',
})
client
.request<getUser, getUserVariables>(query, { id: 10 })
.then(data => console.log(data))
.catch(error => console.log(error))
client.requestSafe<getUser, getUserVariables>(query, { id: 10 }).then(result => {
if (!result.ok) {
throw result.error
}
console.log(`Status ${result.response.status}`, `Data ${result.data.user}`)
})
You can generate types from queries by using GraphQL Code Generator with TypedDocumentNode plugin
# queries.graphql
query getUser($id: Int!) {
user {
id
login
}
}
// index.ts
import { TypedDocumentNode } from '@graphql-typed-document-node/core'
import { AwesomeGraphQLClient } from 'awesome-graphql-client'
import { print } from 'graphql/language/printer'
import { GetCharactersDocument } from './generated'
const gqlClient = new AwesomeGraphQLClient({
endpoint: 'https://rickandmortyapi.com/graphql',
formatQuery: (query: TypedDocumentNode) => print(query),
})
// AwesomeGraphQLClient will infer all types from the passed query automagically:
gqlClient
.request(GetCharactersDocument, { name: 'Rick' })
.then(data => console.log(data))
.catch(error => console.log(error))
Check out full example at examples/typed-document-node
import { AwesomeGraphQLClient, GraphQLRequestError } from 'awesome-graphql-client'
const client = new AwesomeGraphQLClient({
endpoint: '/graphql',
onError(error) {
if (error instanceof GraphQLRequestError) {
console.error(error.message)
console.groupCollapsed('Operation:')
console.log({ query: error.query, variables: error.variables })
console.groupEnd()
} else {
console.error(error)
}
},
})
Internally it uses URLSearchParams API. Consider polyfilling URL standard for this feature to work in IE
client
.request(query, variables, { method: 'GET' })
.then(data => console.log(data))
.catch(err => console.log(err))
formatQuery
import { AwesomeGraphQLClient } from 'awesome-graphql-client'
import { DocumentNode } from 'graphql/language/ast'
import { print } from 'graphql/language/printer'
import gql from 'graphql-tag'
const client = new AwesomeGraphQLClient({
endpoint: '/graphql',
formatQuery: (query: DocumentNode | string) =>
typeof query === 'string' ? query : print(query),
})
const query = gql`
query me {
me {
login
}
}
`
client
.request(query)
.then(data => console.log(data))
.catch(err => console.log(err))
graphql-tag
Recommended approach if you're using graphql-tag
only for syntax highlighting and static analysis such as linting and types generation. It has less computational cost and makes overall smaller bundles. GraphQL fragments are supported too.
import { AwesomeGraphQLClient, gql } from 'awesome-graphql-client'
const client = new AwesomeGraphQLClient({ endpoint: '/graphql' })
const query = gql`
query me {
me {
login
}
}
`
client
.request(query)
.then(data => console.log(data))
.catch(err => console.log(err))
Perfect for Typescript projects. See example above
const { AwesomeGraphQLClient } = require('awesome-graphql-client')
const fetchCookie = require('fetch-cookie')
const client = new AwesomeGraphQLClient({
endpoint: 'http://localhost:8080/graphql',
fetch: fetchCookie(globalThis.fetch),
})
const { AwesomeGraphQLClient, isFileUpload } = require('awesome-graphql-client')
const client = new AwesomeGraphQLClient({
endpoint: 'http://localhost:8080/graphql',
// By default File, Blob, Buffer, Promise and stream-like instances are considered as files.
// You can expand this behaviour by adding a custom predicate
isFileUpload: value => isFileUpload(value) || value instanceof MyCustomFile,
})
https://github.com/lynxtaa/awesome-graphql-client/tree/master/examples
FAQs
GraphQL Client with file upload support for NodeJS and browser
We found that awesome-graphql-client demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The MCP community is launching an official registry to standardize AI tool discovery and let agents dynamically find and install MCP servers.
Research
Security News
Socket uncovers an npm Trojan stealing crypto wallets and BullX credentials via obfuscated code and Telegram exfiltration.
Research
Security News
Malicious npm packages posing as developer tools target macOS Cursor IDE users, stealing credentials and modifying files to gain persistent backdoor access.